🧪 模拟演示
🔧 接入代码
⚙️ 后端签名
📷

微信 JS-SDK 扫码

调用微信原生扫码界面
识别率极高,体验最佳

扫码结果:
-
ℹ️ 当前为模拟模式
实际在微信内使用时:
1. 引入微信 JS-SDK:res.wx.qq.com/open/js/jweixin-1.6.0.js
2. 通过后端接口获取签名配置
3. 在 wx.ready() 中调用 wx.scanQRCode()
① 引入 JS-SDK
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
② wx.config 配置(前端)
③ 调用扫码 API
④ 完整 HTML 示例
Node.js 签名示例
Python 签名示例
签名流程说明
签名步骤:
1. 获取 access_token(GET /cgi-bin/token
2. 用 access_token 获取 jsapi_ticket(GET /cgi-bin/ticket/getticket
3. 将 jsapi_ticket + nonceStr + timestamp + url 按字典序排序后 SHA1 签名
4. 将 signature、appId、timestamp、nonceStr 返回前端

⚠️ 注意:url 必须是当前页面的完整 URL(不含 # 及其后面部分)
模拟微信原生扫码界面
正在识别中...
`; document.getElementById('codeNode').textContent = `// Node.js / Express 后端签名 const express = require('express'); const crypto = require('crypto'); const axios = require('axios'); const app = express(); const APP_ID = 'your_app_id'; const APP_SECRET = 'your_app_secret'; let jsapiTicket = ''; let ticketExpire = 0; // 获取 access_token async function getAccessToken() { const url = \`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=\${APP_ID}&secret=\${APP_SECRET}\`; const { data } = await axios.get(url); return data.access_token; } // 获取 jsapi_ticket async function getJsapiTicket() { if (Date.now() < ticketExpire) return jsapiTicket; const token = await getAccessToken(); const url = \`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=\${token}&type=jsapi\`; const { data } = await axios.get(url); jsapiTicket = data.ticket; ticketExpire = Date.now() + (data.expires_in - 300) * 1000; // 提前5分钟刷新 return jsapiTicket; } // 生成签名 function generateSignature(ticket, nonceStr, timestamp, url) { const str = \`jsapi_ticket=\${ticket}&noncestr=\${nonceStr}×tamp=\${timestamp}&url=\${url}\`; return crypto.createHash('sha1').update(str).digest('hex'); } // 接口:前端获取 wx.config 参数 app.get('/api/wx-config', async (req, res) => { try { const ticket = await getJsapiTicket(); const nonceStr = Math.random().toString(36).substring(2, 15); const timestamp = Math.floor(Date.now() / 1000); const url = decodeURIComponent(req.query.url || ''); const signature = generateSignature(ticket, nonceStr, timestamp, url); res.json({ appId: APP_ID, timestamp, nonceStr, signature }); } catch (e) { res.status(500).json({ error: e.message }); } }); app.listen(3000, () => console.log('Server running on :3000'));`; document.getElementById('codePython').textContent = `# Python / Flask 后端签名 from flask import Flask, request, jsonify import hashlib import random import string import time import requests app = Flask(__name__) APP_ID = 'your_app_id' APP_SECRET = 'your_app_secret' _access_token = '' _token_expire = 0 _jsapi_ticket = '' _ticket_expire = 0 def get_access_token(): global _access_token, _token_expire if time.time() < _token_expire: return _access_token url = f'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={APP_ID}&secret={APP_SECRET}' data = requests.get(url).json() _access_token = data['access_token'] _token_expire = time.time() + data['expires_in'] - 300 return _access_token def get_jsapi_ticket(): global _jsapi_ticket, _ticket_expire if time.time() < _ticket_expire: return _jsapi_ticket token = get_access_token() url = f'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token={token}&type=jsapi' data = requests.get(url).json() _jsapi_ticket = data['ticket'] _ticket_expire = time.time() + data['expires_in'] - 300 return _jsapi_ticket def generate_signature(ticket, nonce_str, timestamp, url): s = f'jsapi_ticket={ticket}&noncestr={nonce_str}×tamp={timestamp}&url={url}' return hashlib.sha1(s.encode()).hexdigest() @app.route('/api/wx-config') def wx_config(): ticket = get_jsapi_ticket() nonce_str = ''.join(random.choices(string.ascii_letters + string.digits, k=16)) timestamp = int(time.time()) url = request.args.get('url', '') signature = generate_signature(ticket, nonce_str, timestamp, url) return jsonify({ 'appId': APP_ID, 'timestamp': timestamp, 'nonceStr': nonce_str, 'signature': signature }) app.run(port=3000) `);