23 KiB
微信JS-SDK集成API文档
📋 文档概述
API模块: 微信JS-SDK集成
适用平台: 移动端 (H5)
技术架构: uni-app 2.x + Vue 2.6.14 + 微信JS-SDK 1.6.0
更新日期: 2025-01-03
文档版本: v1.1.0 (新增微信多媒体文件处理功能)
🎯 功能概述
微信JS-SDK集成模块为移动端应用提供完整的微信浏览器原生功能调用能力,包括分享、扫码、支付、地理位置、图片处理等功能。
核心功能
- ✅ 微信环境检测和SDK初始化
- ✅ 分享功能(朋友圈/朋友)
- ✅ 扫码功能(二维码/条形码)
- ✅ 图片处理(选择/预览/上传)
- ✅ 微信多媒体文件永久保存(解决3天有效期限制)
- ✅ 地理位置(获取/打开地图)
- ✅ 设备信息查询
- ✅ 微信支付调用
- ✅ 接口支持检查
🔧 技术架构
前端架构
mobile/
├── src/
│ ├── utils/
│ │ └── wechat.js # 微信JS-SDK工具类
│ ├── api/
│ │ └── wechat.ts # 微信API接口定义
│ └── components/
│ └── WeChatDemo.vue # 功能演示组件
└── public/
└── index.html # JS-SDK脚本引用
依赖关系
- 微信JS-SDK: 1.6.0 (CDN引入)
- 请求工具: 基于项目统一的request.js
- 加密工具: 使用现有的crypto.js
- UI组件: uview-ui 2.0.38
📚 前端API文档
微信工具类 (wechat.js)
1. 初始化相关
init(options)
初始化微信JS-SDK配置
方法签名:
async init(options = {})
参数说明:
interface InitOptions {
url?: string; // 当前页面URL,默认自动获取
jsApiList?: string[]; // 需要使用的API列表,默认使用全部
debug?: boolean; // 是否开启调试模式,默认根据环境
}
返回值:
Promise<WeChatConfig>
使用示例:
import weChatSDK from '@/utils/wechat.js';
// 基础初始化
await weChatSDK.init();
// 自定义配置
await weChatSDK.init({
debug: true,
jsApiList: ['chooseImage', 'scanQRCode', 'getLocation']
});
isWeChatBrowser()
检查是否在微信浏览器中
方法签名:
isWeChatBrowser()
返回值:
boolean
使用示例:
if (weChatSDK.isWeChatBrowser()) {
console.log('在微信浏览器中');
} else {
console.log('不在微信浏览器中');
}
2. 分享功能
shareTimeline(shareData)
分享到朋友圈
方法签名:
async shareTimeline(shareData)
参数说明:
interface ShareTimelineData {
title: string; // 分享标题
link: string; // 分享链接
imgUrl: string; // 分享图标URL
}
使用示例:
await weChatSDK.shareTimeline({
title: '智慧校园移动应用',
link: 'https://example.com/app',
imgUrl: 'https://example.com/logo.png'
});
shareAppMessage(shareData)
分享给朋友
方法签名:
async shareAppMessage(shareData)
参数说明:
interface ShareAppMessageData {
title: string; // 分享标题
desc: string; // 分享描述
link: string; // 分享链接
imgUrl: string; // 分享图标URL
}
使用示例:
await weChatSDK.shareAppMessage({
title: '智慧校园',
desc: '基于uni-app的校园管理系统',
link: 'https://example.com/app',
imgUrl: 'https://example.com/logo.png'
});
3. 扫码功能
scanQRCode(options)
微信扫一扫
方法签名:
async scanQRCode(options = {})
参数说明:
interface ScanOptions {
needResult?: number; // 是否返回扫描结果,0不返回,1返回,默认1
scanType?: string[]; // 扫码类型,默认['qrCode', 'barCode']
}
返回值:
Promise<{
resultStr: string; // 扫描结果
}>
使用示例:
// 扫描二维码和条形码
const result = await weChatSDK.scanQRCode();
console.log('扫码结果:', result.resultStr);
// 只扫描二维码
const qrResult = await weChatSDK.scanQRCode({
scanType: ['qrCode']
});
4. 图片功能
chooseImage(options)
选择图片
方法签名:
async chooseImage(options = {})
参数说明:
interface ChooseImageOptions {
count?: number; // 图片数量,默认1,最多9张
sizeType?: string[]; // 图片尺寸,默认['original', 'compressed']
sourceType?: string[]; // 图片来源,默认['album', 'camera']
}
返回值:
Promise<{
localIds: string[]; // 图片本地ID列表
}>
使用示例:
// 选择1张压缩图片
const result = await weChatSDK.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera']
});
console.log('选中图片:', result.localIds);
previewImage(options)
预览图片
方法签名:
async previewImage(options)
参数说明:
interface PreviewImageOptions {
current: string; // 当前显示图片的链接
urls: string[]; // 需要预览的图片链接列表
}
使用示例:
await weChatSDK.previewImage({
current: 'https://example.com/image1.jpg',
urls: [
'https://example.com/image1.jpg',
'https://example.com/image2.jpg'
]
});
5. 地理位置
getLocation(options)
获取地理位置
方法签名:
async getLocation(options = {})
参数说明:
interface LocationOptions {
type?: string; // 坐标类型,'wgs84'或'gcj02',默认'gcj02'
}
返回值:
Promise<{
latitude: number; // 纬度
longitude: number; // 经度
speed: number; // 速度(米/秒)
accuracy: number; // 精度(米)
}>
使用示例:
const location = await weChatSDK.getLocation({
type: 'gcj02'
});
console.log(`位置: ${location.latitude}, ${location.longitude}`);
console.log(`精度: ${location.accuracy}米`);
openLocation(location)
打开地图
方法签名:
async openLocation(location)
参数说明:
interface OpenLocationData {
latitude: number; // 纬度
longitude: number; // 经度
name?: string; // 位置名称
address?: string; // 地址详情
scale?: number; // 地图缩放级别,默认14
}
使用示例:
await weChatSDK.openLocation({
latitude: 39.908692,
longitude: 116.397477,
name: '天安门',
address: '北京市东城区天安门广场',
scale: 16
});
6. 设备信息
getNetworkType()
获取网络状态
方法签名:
async getNetworkType()
返回值:
Promise<{
networkType: string; // 网络类型:wifi/2g/3g/4g/5g/unknown/none
}>
使用示例:
const network = await weChatSDK.getNetworkType();
console.log('网络类型:', network.networkType);
7. 支付功能
chooseWXPay(payInfo)
微信支付
方法签名:
async chooseWXPay(payInfo)
参数说明:
interface PayInfo {
timestamp: string; // 时间戳
nonceStr: string; // 随机字符串
package: string; // 订单详情扩展字符串
signType?: string; // 签名方式,默认'MD5'
paySign: string; // 签名
}
使用示例:
await weChatSDK.chooseWXPay({
timestamp: '1640995200',
nonceStr: 'Wm3WZYTPz0wzccnW',
package: 'prepay_id=wx1234567890abcdef',
signType: 'MD5',
paySign: '0f9de62fce790f9a083d5c99e95740ceb90c27ed'
});
8. 工具方法
checkJsApi(jsApiList)
检查接口支持
方法签名:
async checkJsApi(jsApiList)
参数说明:
jsApiList: string[] // 需要检查的接口列表
返回值:
Promise<{
checkResult: {
[apiName: string]: boolean; // 接口名称和支持状态的映射
}
}>
使用示例:
const result = await weChatSDK.checkJsApi([
'chooseImage',
'scanQRCode',
'getLocation'
]);
console.log('chooseImage支持:', result.checkResult.chooseImage);
console.log('scanQRCode支持:', result.checkResult.scanQRCode);
closeWindow()
关闭当前网页窗口
方法签名:
closeWindow()
使用示例:
weChatSDK.closeWindow();
🌐 后端API接口
基础信息
接口基础路径: /system/wechat
认证方式: Bearer Token
请求格式: application/json
响应格式: application/json
接口列表
1. 获取微信JS-SDK配置
接口描述: 获取微信JS-SDK初始化所需的配置信息
接口地址: POST /system/wechat/config
请求参数:
{
"url": "https://example.com/app" // 当前页面URL
}
响应示例:
{
"code": 200,
"msg": "操作成功",
"data": {
"appId": "wx1234567890abcdef",
"timestamp": 1640995200,
"nonceStr": "Wm3WZYTPz0wzccnW",
"signature": "0f9de62fce790f9a083d5c99e95740ceb90c27ed"
}
}
2. 保存微信媒体文件到服务器
接口描述: 将微信临时媒体文件下载并保存到自己的OSS服务器,解决微信媒体文件3天有效期限制
背景说明:
- 微信JS-SDK的
wx.uploadImage只是将图片上传到微信临时服务器,获得serverId(也就是media_id) - 这个serverId有效期只有3天,过期后无法访问
- 本接口通过微信多媒体API将文件从微信服务器下载到我们的OSS存储,实现永久保存
接口地址: POST /system/wechat/upload
请求参数:
{
"mediaId": "wx_media_123456", // 微信媒体文件ID(wx.uploadImage返回的serverId)
"type": "image" // 媒体类型:image/voice/video/thumb
}
处理流程:
- 使用微信access_token从微信多媒体接口下载文件
- 根据Content-Type自动识别文件类型和扩展名
- 将文件上传到项目的OSS存储服务
- 返回文件在我们服务器上的访问信息
响应示例:
{
"code": 200,
"msg": "上传成功",
"data": {
"mediaId": "wx_media_123456",
"ossId": 12345,
"fileName": "20250103/wechat_media_wx_media_123456_a1b2c3.jpg",
"originalName": "wechat_media_wx_media_123456.jpg",
"url": "https://oss.example.com/files/20250103/wechat_media_wx_media_123456_a1b2c3.jpg",
"fileSuffix": ".jpg",
"fileSize": 256789,
"contentType": "image/jpeg",
"downloadTime": 1640995200000,
"status": "success"
}
}
错误响应示例:
{
"code": 500,
"msg": "处理微信媒体文件失败: 微信媒体文件下载失败: media_id invalid",
"data": null
}
3. 测试微信媒体文件下载
接口描述: 测试从微信服务器下载媒体文件(与上传接口功能相同,用于直接测试下载功能)
接口地址: GET /system/wechat/download
请求参数:
?mediaId=wx_media_123456
响应格式: JSON(与上传接口返回格式相同)
使用场景:
- 测试微信媒体文件下载功能
- 单独下载特定的微信媒体文件
- 开发调试和接口验证
4. 获取微信用户信息
接口描述: 通过微信授权码获取用户信息
接口地址: GET /system/wechat/userinfo
请求参数:
?code=wx_auth_code_123456
响应示例:
{
"code": 200,
"msg": "获取成功",
"data": {
"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
"nickname": "用户昵称",
"headimgurl": "https://example.com/avatar.jpg",
"unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
}
}
5. 创建微信支付订单
接口描述: 创建微信支付订单并返回支付参数
接口地址: POST /system/wechat/pay/create
请求参数:
{
"body": "商品描述",
"total_fee": 100, // 金额(分)
"trade_type": "JSAPI",
"openid": "用户openid"
}
响应示例:
{
"code": 200,
"msg": "创建成功",
"data": {
"timestamp": "1640995200",
"nonceStr": "Wm3WZYTPz0wzccnW",
"package": "prepay_id=wx1234567890abcdef",
"signType": "MD5",
"paySign": "0f9de62fce790f9a083d5c99e95740ceb90c27ed"
}
}
6. 查询支付状态
接口描述: 查询微信支付订单状态
接口地址: GET /system/wechat/pay/query
请求参数:
?order_id=ORDER_123456
响应示例:
{
"code": 200,
"msg": "查询成功",
"data": {
"order_id": "ORDER_123456",
"trade_state": "SUCCESS",
"transaction_id": "wx_trans_123456",
"total_fee": 100
}
}
🎨 使用示例
完整使用流程
<template>
<view class="wechat-page">
<!-- 初始化按钮 -->
<button @click="initWeChatSDK" :disabled="isInitialized">
{{ isInitialized ? '已初始化' : '初始化微信SDK' }}
</button>
<!-- 功能按钮 -->
<button @click="scanQRCode" :disabled="!isInitialized">扫一扫</button>
<button @click="chooseAndPreviewImage" :disabled="!isInitialized">选择图片</button>
<button @click="shareToFriends" :disabled="!isInitialized">分享给朋友</button>
<button @click="getLocationAndOpen" :disabled="!isInitialized">获取位置</button>
</view>
</template>
<script>
import weChatSDK from '@/utils/wechat.js';
export default {
data() {
return {
isInitialized: false
};
},
mounted() {
this.checkWeChatEnvironment();
},
methods: {
// 检查微信环境
checkWeChatEnvironment() {
if (!weChatSDK.isWeChatBrowser()) {
uni.showModal({
title: '提示',
content: '请在微信中打开',
showCancel: false
});
}
},
// 初始化微信SDK
async initWeChatSDK() {
try {
await weChatSDK.init({
debug: process.env.NODE_ENV === 'development'
});
this.isInitialized = true;
uni.showToast({ title: '初始化成功', icon: 'success' });
} catch (error) {
console.error('初始化失败:', error);
uni.showToast({ title: '初始化失败', icon: 'none' });
}
},
// 扫码功能
async scanQRCode() {
try {
const result = await weChatSDK.scanQRCode();
uni.showModal({
title: '扫码结果',
content: result.resultStr,
showCancel: false
});
} catch (error) {
uni.showToast({ title: '扫码失败', icon: 'none' });
}
},
// 选择和预览图片
async chooseAndPreviewImage() {
try {
const result = await weChatSDK.chooseImage({
count: 3,
sizeType: ['compressed']
});
if (result.localIds.length > 0) {
await weChatSDK.previewImage({
current: result.localIds[0],
urls: result.localIds
});
}
} catch (error) {
uni.showToast({ title: '操作失败', icon: 'none' });
}
},
// 分享给朋友
async shareToFriends() {
try {
await weChatSDK.shareAppMessage({
title: '智慧校园',
desc: '基于uni-app的校园管理系统',
link: window.location.href,
imgUrl: 'https://example.com/logo.png'
});
uni.showToast({ title: '分享配置成功', icon: 'success' });
} catch (error) {
uni.showToast({ title: '分享配置失败', icon: 'none' });
}
},
// 获取位置并打开地图
async getLocationAndOpen() {
try {
const location = await weChatSDK.getLocation();
await weChatSDK.openLocation({
latitude: location.latitude,
longitude: location.longitude,
name: '当前位置',
address: '通过微信JS-SDK获取',
scale: 16
});
} catch (error) {
uni.showToast({ title: '定位失败', icon: 'none' });
}
}
}
};
</script>
🔧 配置说明
微信公众平台配置
-
JS接口安全域名配置
- 登录微信公众平台
- 进入"设置" → "公众号设置" → "功能设置"
- 配置"JS接口安全域名"
- 填入网站域名(不包含http://)
-
接口权限获取
- 确保服务号已认证
- 开通所需的接口权限
- 获取AppID和AppSecret
后端配置要求
-
微信配置
const wechatConfig = { appId: 'wx1234567890abcdef', appSecret: '你的AppSecret', token: '你的Token', encodingAESKey: '你的EncodingAESKey' }; -
签名算法
// 签名算法实现(示例) function generateSignature(jsapi_ticket, noncestr, timestamp, url) { const string1 = `jsapi_ticket=${jsapi_ticket}&noncestr=${noncestr}×tamp=${timestamp}&url=${url}`; return sha1(string1); }
🔧 微信多媒体接口详解
什么是微信多媒体接口?
微信多媒体接口是微信公众平台后端API,用于处理通过微信JS-SDK上传的临时媒体文件。
完整的图片处理流程
用户操作 微信前端 微信服务器 项目后端 项目OSS
| | | | |
1. 选择图片 -----> | | | |
| | | | |
2. 调用wx.uploadImage -----------> | 临时存储3天 | |
| | | (获得serverId) | |
| | <------------ | | |
| | | | |
3. 调用后端接口 -----> POST /system/wechat/upload | |
| | | | |
| | 4. 使用access_token | |
| | 下载文件 <--------- | |
| | | | |
| | | 返回文件数据 --> | |
| | | | |
| | | 5. 上传OSS ----------> | 永久存储
| | | | |
| | <------------ | 返回OSS访问地址 <------------ |
核心微信API接口
1. 获取access_token
GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
2. 下载多媒体文件
GET https://api.weixin.qq.com/cgi-bin/media/get?access_token=ACCESS_TOKEN&media_id=MEDIA_ID
前端集成示例
// 完整的图片上传并保存流程
async uploadAndSaveImage() {
try {
// 1. 选择图片
const chooseResult = await wx.chooseImage({
count: 1,
sizeType: ['compressed'],
sourceType: ['album', 'camera']
});
const localId = chooseResult.localIds[0];
// 2. 上传到微信服务器
const uploadResult = await wx.uploadImage({
localId: localId,
isShowProgressTips: 1
});
const serverId = uploadResult.serverId;
console.log('微信服务器ID:', serverId);
// 3. 调用后端接口保存到自己的服务器
const saveResponse = await uni.request({
url: '/system/wechat/upload',
method: 'POST',
header: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token'
},
data: {
mediaId: serverId,
type: 'image'
}
});
if (saveResponse.data.code === 200) {
const savedFile = saveResponse.data.data;
console.log('文件已保存:', savedFile.url);
console.log('OSS ID:', savedFile.ossId);
// 现在可以长期使用这个URL了
this.showImage(savedFile.url);
}
} catch (error) {
console.error('处理失败:', error);
}
}
后端实现关键点
1. 文件类型识别
private String getFileExtensionByContentType(String contentType) {
switch (contentType.toLowerCase()) {
case "image/jpeg": return ".jpg";
case "image/png": return ".png";
case "image/gif": return ".gif";
// ... 更多类型
default: return ".unknown";
}
}
2. 错误处理
// 检查微信API返回的错误
String contentType = response.header("Content-Type");
if (contentType != null && contentType.contains("application/json")) {
// 返回的是JSON错误信息
JSONObject errorJson = JSONUtil.parseObj(response.body());
throw new ServiceException("微信媒体文件下载失败: " + errorJson.getStr("errmsg"));
}
🚨 注意事项
1. 安全考虑
- ⚠️ AppSecret等敏感信息只能在服务端使用
- ⚠️ 签名计算必须在服务端完成
- ⚠️ 分享图标等资源使用HTTPS地址
- ⚠️ access_token需要缓存,避免频繁获取
- ⚠️ 微信媒体文件有3天有效期,需及时下载保存
2. 调试技巧
- 📱 使用微信开发者工具进行调试
- 🐛 开启debug模式查看详细错误信息
- 🔍 检查JS接口安全域名配置
- 🔍 检查access_token是否有效
- 🔍 验证media_id是否在3天有效期内
3. 常见问题
- invalid signature: 检查签名算法和URL参数
- permission denied: 确认接口权限和jsApiList配置
- config:fail: 检查配置参数完整性
- media_id invalid: 媒体文件已过期或不存在
- access_token invalid: Token已过期,需要重新获取
- 下载失败: 检查网络连接和微信服务器状态
4. 性能优化
- 🚀 access_token缓存7200秒(提前300秒刷新)
- 🚀 支持多种文件格式自动识别
- 🚀 集成OSS存储,支持CDN加速
- 🚀 异步处理大文件上传
📱 兼容性
支持的微信版本
- iOS微信: 6.0.2+
- Android微信: 6.0.2+
支持的功能
- ✅ 基础分享功能(所有认证服务号)
- ✅ 图像和音频处理
- ✅ 地理位置服务
- ✅ 设备信息查询
- ✅ 扫一扫功能
- ✅ 微信支付(需开通)
🔗 相关资源
文档维护: 开发团队
最后更新: 2025-01-03
API版本: v1.0.0