188 lines
4.4 KiB
Markdown
188 lines
4.4 KiB
Markdown
# uniapp H5 调用微信扫一扫配置文档
|
||
|
||
## 一、微信 JSSDK 加载
|
||
|
||
**方式:通过 CDN 加载微信官方 JSSDK**
|
||
|
||
在 `index.html` 的 `<head>` 中添加:
|
||
|
||
```html
|
||
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
|
||
```
|
||
|
||
> **注意:** 不要使用 `import wx from 'jweixin-module'` 或 npm 包方式导入,uni-app 会错误解析导致构建失败。
|
||
|
||
---
|
||
|
||
## 二、wxsdk.js 封装
|
||
|
||
创建 `utils/wxsdk.js`:
|
||
|
||
```javascript
|
||
// utils/wxsdk.js
|
||
import { wechatApi } from '@/api/index.js'
|
||
|
||
// 注意:是 jWeixin,不是 wx
|
||
// window.wx 会被 uni-app 框架占用为 Vue 模块
|
||
const wx = window.jWeixin
|
||
|
||
/**
|
||
* 初始化微信 JS-SDK
|
||
*/
|
||
export async function initWxConfig() {
|
||
const url = window.location.href.split('#')[0]
|
||
try {
|
||
const data = await wechatApi.getJssdkConfig(url)
|
||
const { app_id, timestamp, nonce_str, signature } = data
|
||
|
||
return new Promise((resolve, reject) => {
|
||
wx.config({
|
||
debug: true,
|
||
appId: app_id,
|
||
timestamp: timestamp,
|
||
nonceStr: nonce_str,
|
||
signature: signature,
|
||
jsApiList: ['scanQRCode']
|
||
})
|
||
wx.ready(() => {
|
||
console.log('微信 SDK 就绪')
|
||
resolve()
|
||
})
|
||
wx.error((err) => {
|
||
reject(err)
|
||
})
|
||
})
|
||
} catch (e) {
|
||
throw e
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 调起微信扫一扫
|
||
* @returns {Promise<string>} 扫码结果字符串
|
||
*/
|
||
export function wxScan() {
|
||
return new Promise((resolve, reject) => {
|
||
wx.scanQRCode({
|
||
needResult: 1,
|
||
scanType: ['qrCode', 'barCode'],
|
||
success(res) {
|
||
resolve(res.resultStr)
|
||
},
|
||
fail(err) {
|
||
reject(new Error(err?.errMsg || '扫码失败'))
|
||
}
|
||
})
|
||
})
|
||
}
|
||
|
||
/**
|
||
* 检查是否在微信环境中
|
||
*/
|
||
export function isInWechat() {
|
||
return /micromessenger/i.test(navigator.userAgent)
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 三、后端接口要求
|
||
|
||
后端需提供 `/api/c/v1/wechat/jssdk-config` 接口,返回格式:
|
||
|
||
```json
|
||
{
|
||
"app_id": "wx1234567890",
|
||
"timestamp": 1234567890,
|
||
"nonce_str": "randomstring",
|
||
"signature": "xxxxx"
|
||
}
|
||
```
|
||
|
||
> **注意:** `nonce_str` 必须与生成 signature 时使用的一致
|
||
|
||
---
|
||
|
||
## 四、前端调用示例
|
||
|
||
```javascript
|
||
import { initWxConfig, wxScan, isInWechat } from '@/utils/wxsdk.js'
|
||
|
||
async function handleScan() {
|
||
if (!isInWechat()) {
|
||
uni.showToast({ title: '请在微信环境中使用', icon: 'none' })
|
||
return
|
||
}
|
||
|
||
try {
|
||
// 1. 初始化微信 SDK 配置
|
||
await initWxConfig()
|
||
|
||
// 2. 调起扫一扫
|
||
const result = await wxScan()
|
||
console.log('扫码结果:', result)
|
||
// 在此处理扫码结果
|
||
} catch (err) {
|
||
console.error('扫码错误:', err)
|
||
uni.showToast({ title: err.message || JSON.stringify(err), icon: 'none' })
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 五、注意事项
|
||
|
||
| 问题 | 原因 | 解决方案 |
|
||
|------|------|----------|
|
||
| `window.wx` 输出 `Module {$emit...}` | `window.wx` 被 uni-app 框架占用为 Vue 事件模块 | 使用 `window.jWeixin` |
|
||
| `jweixin-module` 打包报 `"default" is not exported` | uni 构建系统错误解析无 default export 的 UMD 模块 | 使用 CDN 加载,不走 npm |
|
||
| `wx.scanQRCode is not a function` | 微信 SDK 未正确加载 | 确认 `window.jWeixin` 有值 |
|
||
| 扫码提示 `{}` | `catch` 捕获空错误对象 | 需将错误信息转换为 `Error` 对象返回 |
|
||
|
||
---
|
||
|
||
## 六、调试建议
|
||
|
||
在微信开发者工具中打开控制台,检查以下变量:
|
||
|
||
```javascript
|
||
// 错误情况:被 uni-app 框架占用为 Vue 模块
|
||
window.wx
|
||
// 输出:Module {$emit: ƒ, $off: ƒ, $on: ƒ, $once: ƒ, ...}
|
||
|
||
// 正确情况:微信 JSSDK
|
||
window.jWeixin
|
||
// 输出:{config: ƒ, ready: ƒ, error: ƒ, checkJsApi: ƒ, ...}
|
||
```
|
||
|
||
---
|
||
|
||
## 七、完整文件路径
|
||
|
||
```
|
||
project/
|
||
├── index.html # 引入微信 JSSDK CDN
|
||
├── utils/
|
||
│ └── wxsdk.js # 微信扫一扫封装
|
||
└── api/
|
||
└── modules/
|
||
└── wechat.js # 后端接口封装
|
||
```
|
||
|
||
`api/modules/wechat.js` 示例:
|
||
|
||
```javascript
|
||
import request from '@/utils/request.js'
|
||
|
||
export const wechatApi = {
|
||
getJssdkConfig(url) {
|
||
return request({
|
||
url: '/api/c/v1/wechat/jssdk-config',
|
||
method: 'GET',
|
||
data: { url }
|
||
})
|
||
}
|
||
}
|
||
```
|