引言:由于时间问题,后端拒绝配合,只给提供 ticket,所以没有办法,前端卑微只能靠自己,找了好多办法,终于搞定,虽然最后也没用上
注:强烈不推荐使用,这玩意都是后端搞得,前端搞那不是开玩笑嘛
框架:vue3+ts+vite+vant+pinia, 打包 h5 内嵌微信小程序
- 排序对象的属性名数组
const objKeySort = (arys: any) => {
//先用Object内置类的keys方法获取要排序对象的属性名数组,再利用Array的sort方法进行排序
const newkey = Object.keys(arys).sort();
// console.log('newkey=' + newkey);
let newObj = ''; //创建一个新的对象,用于存放排好序的键值对
for (let i = 0; i < newkey.length; i++) {
//遍历newkey数组
newObj += [newkey[i]] + '=' + arys[newkey[i]] + '&';
}
return newObj.substring(0, newObj.length - 1);
};
2.生成指定长度的随机字符串,作为nonceStr
const randomString = (length: any) => {
// 定义字符串中的字符
const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
// 循环指定长度
for (let i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
// 返回生成的字符串
return result;
};
-
获取 ticket,这个必须要后端了,前端真的搞不了
-
获取签名,使用 sha1 加密
首先 排序
const sortStr = objKeySort({
// eslint-disable-next-line camelcase
jsapi_ticket: res.data,
noncestr: nonceStr, // nocestr必须全部小写,当初为了省事,直接用的大写 S,结果踩坑,找了好久才发现问题,差点崩溃了。
timestamp,
url: window.location.href.split('#')[0],
});
pnpm install js-sha1
import { sha1 } from 'js-sha1';
const signature = sha1(sortStr);
- 配置 wx jssdk
export const wxSetConfig = async (debug: boolean = false) => {
const nonceStr = randomString(16);
const timestamp = Math.round(new Date().getTime() / 1000);
_wx.config({
debug: debug, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp, // 必填,生成签名的时间戳
nonceStr, // 必填,生成签名的随机串
signature, // 必填,签名
jsApiList: ['scanQRCode'], // 必填,需要使用的JS接口列表
});
};
完整代码如下
import _wx from 'weixin-js-sdk';
import Request from './request/';
import { sha1 } from 'js-sha1';
const http = new Request();
const objKeySort = (arys: any) => {
//先用Object内置类的keys方法获取要排序对象的属性名数组,再利用Array的sort方法进行排序
const newkey = Object.keys(arys).sort();
// console.log('newkey=' + newkey);
let newObj = ''; //创建一个新的对象,用于存放排好序的键值对
for (let i = 0; i < newkey.length; i++) {
//遍历newkey数组
newObj += [newkey[i]] + '=' + arys[newkey[i]] + '&';
}
return newObj.substring(0, newObj.length - 1);
};
// 生成指定长度的随机字符串
const randomString = (length: any) => {
// 定义字符串中的字符
const chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
let result = '';
// 循环指定长度
for (let i = length; i > 0; --i) result += chars[Math.floor(Math.random() * chars.length)];
// 返回生成的字符串
return result;
};
/** 获取wx-ticket配置信息 */
export const getPolicy = () => {
return http.post('');
};
export const wxSetConfig = async (debug: boolean = false) => {
const res = await getPolicy();
const nonceStr = randomString(16);
const timestamp = Math.round(new Date().getTime() / 1000);
const sortStr = objKeySort({
jsapi_ticket: res.data,
noncestr: nonceStr,
timestamp,
url: window.location.href.split('#')[0], // 域名需在微信公众号 js 安全接口内配置
});
_wx.config({
debug: debug, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '', // 必填,公众号的唯一标识
timestamp, // 必填,生成签名的时间戳
nonceStr, // 必填,生成签名的随机串
signature: sha1(sortStr), // 必填,签名
jsApiList: ['scanQRCode'], // 必填,需要使用的JS接口列表
});
};