添加了服务端实现方式

This commit is contained in:
2025-08-13 23:43:25 +08:00
parent fd0de3b457
commit ebb617bb96
2 changed files with 203 additions and 7 deletions

208
README.MD
View File

@@ -98,6 +98,14 @@ wxSDK({
### `callback.error(error)`
当发生错误时触发,参数为错误对象
## 注意事项
1. **跨域问题**:确保后端签名接口支持 CORS 或使用代理
2. **URL 一致性**:签名 URL 必须与当前页面 URL 完全一致(不含 hash
3. **HTTPS**:微信要求所有页面必须使用 HTTPS
4. **开放标签**:使用开放标签需在微信公众平台申请
5. **图标大小**:微信分享图标建议尺寸 200×200 像素
## 后端接口要求
SDK 需要调用后端接口获取微信签名,接口应返回以下格式的 JSON 数据:
@@ -111,10 +119,198 @@ SDK 需要调用后端接口获取微信签名,接口应返回以下格式的
}
```
## 注意事项
## 后端 Express 实现
1. **跨域问题**:确保后端签名接口支持 CORS 或使用代理
2. **URL 一致性**:签名 URL 必须与当前页面 URL 完全一致(不含 hash
3. **HTTPS**:微信要求所有页面必须使用 HTTPS
4. **开放标签**:使用开放标签需在微信公众平台申请
5. **图标大小**:微信分享图标建议尺寸 200×200 像素
### 环境要求
1. Node.js 14+
2. Express 4.x
3. Axios 1.x
### 安装依赖
```bash
npm install express axios
```
### 具体实现
```javascript
const express = require('express');
const axios = require('axios');
const crypto = require('crypto');
const router = express.Router();
// 缓存 access_token 和 ticket
let cacheToken = null;
let cacheTicket = null;
let tokenExpireTime = 0;
let ticketExpireTime = 0;
// 微信分享签名接口
router.get('/wxShare', async (req, res) => {
// 微信公众号配置
const appId = 'appId';
const appsecret = 'appsecret';
// 获取前端传递的当前页面 URL
const { url } = req.query;
// 验证参数
if (!url) {
return res.status(400).json({
code: 400,
message: 'URL参数不能为空'
});
}
try {
// 检查并刷新 access_token
const now = Math.floor(Date.now() / 1000);
if (!cacheToken || now >= tokenExpireTime) {
const tokenResponse = await axios.get(
`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appId}&secret=${appsecret}`
);
if (tokenResponse.data.errcode) {
throw new Error(`获取access_token失败: ${tokenResponse.data.errmsg}`);
}
cacheToken = tokenResponse.data.access_token;
// 提前10分钟过期
tokenExpireTime = now + tokenResponse.data.expires_in - 600;
}
// 检查并刷新 ticket
if (!cacheTicket || now >= ticketExpireTime) {
const ticketResponse = await axios.get(
`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${cacheToken}&type=jsapi`
);
if (ticketResponse.data.errcode !== 0) {
throw new Error(`获取ticket失败: ${ticketResponse.data.errmsg}`);
}
cacheTicket = ticketResponse.data.ticket;
// 提前10分钟过期
ticketExpireTime = now + ticketResponse.data.expires_in - 600;
}
// 生成签名
const nonceStr = generateNonceStr(16);
const timestamp = Math.floor(Date.now() / 1000);
const signature = generateSignature({
jsapi_ticket: cacheTicket,
noncestr: nonceStr,
timestamp,
url
});
res.json({
appId,
nonceStr,
timestamp,
signature
});
} catch (err) {
console.error('微信分享签名错误:', err);
// 重置缓存
cacheToken = null;
cacheTicket = null;
res.status(500).json({
code: 500,
message: '服务器内部错误',
error: err.message
});
}
});
// 生成随机字符串
function generateNonceStr(length = 16) {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
let nonceStr = '';
for (let i = 0; i < length; i++) {
nonceStr += chars.charAt(Math.floor(Math.random() * chars.length));
}
return nonceStr;
}
// 生成签名
function generateSignature(params) {
const string = Object.keys(params)
.sort()
.map(key => `${key}=${params[key]}`)
.join('&');
return crypto.createHash('sha1').update(string).digest('hex');
}
module.exports = router;
```
### 错误响应
```json
{
"code": 400,
"message": "URL参数不能为空"
}
```
```json
{
"code": 500,
"message": "服务器内部错误",
"error": "获取access_token失败: invalid appid"
}
```
### 启动服务
在 `app.js` 中集成路由:
```javascript
const express = require('express');
const wxShareRouter = require('./routes/wxShare');
const app = express();
// 中间件
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
// 路由
app.use('/api', wxShareRouter);
// 错误处理
app.use((err, req, res, next) => {
console.error(err.stack);
res.status(500).send('服务器错误');
});
// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服务器运行在端口 ${PORT}`);
});
```
## 常见问题
### 1. 签名无效 (invalid signature)
可能原因:
- URL 不一致(前端传入的 URL 必须与当前页面完全一致)
- 时间戳不一致(确保服务器时间准确)
- 签名算法错误(严格按照微信文档实现)
解决方案:
- 验证前端传入的 URL 是否去除 hash 部分
- 检查服务器时间是否同步
- 使用微信官方签名校验工具验证

View File

@@ -1,6 +1,6 @@
{
"name": "wxsdk-pure",
"version": "1.0.2",
"version": "1.0.3",
"description": "微信分享 SDK 封装",
"main": "index.js",
"scripts": {