记录如何在uni-app中使用微信JS-SDK
前段时间因为修改bug的原因学习了下如何在uni-app下面使用多图上传,所以基于uni-app做了一个微信JS-SDK调用的Demo
# 依赖安装
- npm命令方式
npm install jweixin-module --save
- 下载文件方式
这里我们使用了非npm安装的方式
# 页面引用
在需要使用微信JS-SDK功能的页面引入
<script>
function getLocalImgDataPromise(localId) {
return new Promise((resolve, reject) => {
wx.getLocalImgData({
localId: localId,
success: function(res) {
resolve(res)
},
fail: function(err) {
reject(err)
}
});
})
}
function base64ToBlob(dataurl) {
let arr = dataurl.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
let bstr = atob(arr[1]);
let n = bstr.length;
let u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {
type: mime
});
}
import wx from '@/common/js/jweixin-module/index.js'
export default {
data() {
return {
upload_picture_list: []
}
},
onLoad() {
//获取微信公众号的配置
uni.request({
url: 'http://localhost:4000/sig',
data: {
url: location.href.split('#')[0]
},
success: res => {
var s = res.data;
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: s.data.appId, // 必填,公众号的唯一标识
timestamp: s.data.timestamp, // 必填,生成签名的时间戳
nonceStr: s.data.noncestr, // 必填,生成签名的随机串
signature: s.data.signature.toLowerCase(), // 必填,签名,见附录1
jsApiList: [
'chooseImage',
'previewImage',
"getLocalImgData",
'uploadImage',
]
});
if (typeof callback === 'function') {
callback(res.data);
}
wx.ready(() => {
wx.checkJsApi({
// 需要检测的JS接口列表
jsApiList: ['chooseImage'],
success: function(res) {
console.log("res: " + res);
}
});
})
},
fail: err => {
console.log('request fail', err);
}
});
},
methods: {
previewImg(index) {
let that = this
uni.previewImage({
current: index,
urls: that.upload_picture_list
});
},
chooseImage() {
let _this = this
wx.chooseImage({
success: async (res) => {
let localIds = res.localIds;
for (let i = 0, len = localIds.length; i < len; i++) {
let imgDataRes = await getLocalImgDataPromise(localIds[i])
const localData = imgDataRes.localData
let imageBase64 = '';
if (localData.indexOf('data:image') == 0) {
//苹果的直接赋值,默认生成'data:image/jpeg;base64,'的头部拼接
imageBase64 = localData;
} else {
//此处是安卓中的唯一得坑!在拼接前需要对localData进行换行符的全局替换
//此时一个正常的base64图片路径就完美生成赋值到img的src中了
imageBase64 = 'data:image/jpeg;base64,' + localData.replace(
/\n/g, '');
}
// let blob = base64ToBlob(imageBase64)
_this.upload_picture_list.push(imageBase64);
}
}
});
}
}
}
</script>
# 后台签名方法(nodejs)
这里我们使用koa框架来实现签名,详情可以参考上次分享的文章基于koa实现的微信JS-SDK调用Demo
uni-app项目根目录下的server文件夹下即为示例后端代码,执行node app.js
即可,下面是签名核心方法:
router.get('/sig', async (ctx, next) => {
try {
//获取当前url
let url =
ctx.request.protocol + '://' + ctx.request.host + ctx.request.originalUrl;
if (ctx.query.url) {
url = ctx.query.url;
}
ctx.data = await sign(url);
} catch (e) {
console.log(e);
}
await next();
});
async function sign(url) {
let sig = {},
noncestr = config.noncestr,
timestamp = Math.floor(Date.now() / 1000), //精确到秒
jsapi_ticket;
if (cache.get('ticket')) {
jsapi_ticket = cache.get('ticket');
sig = {
appId: config.appid,
noncestr: noncestr,
timestamp: timestamp,
url: url,
jsapi_ticket: jsapi_ticket,
signature: sha1(
'jsapi_ticket=' +
jsapi_ticket +
'&noncestr=' +
noncestr +
'×tamp=' +
timestamp +
'&url=' +
url
),
};
} else {
// 获取 token
let tokenRes = await rp({
uri:
config.accessTokenUrl +
'?grant_type=' +
config.grant_type +
'&appid=' +
config.appid +
'&secret=' +
config.secret,
});
tokenRes = JSON.parse(tokenRes);
// 获取 ticket
let ticketRes = await rp({
uri:
config.ticketUrl +
'?access_token=' +
tokenRes.access_token +
'&type=jsapi',
});
var ticketMap = JSON.parse(ticketRes);
// 加入缓存
cache.put('ticket', ticketMap.ticket, config.cache_duration);
sig = {
appId: config.appid,
noncestr: noncestr,
timestamp: timestamp,
url: url,
jsapi_ticket: ticketMap.ticket,
signature: sha1(
'jsapi_ticket=' +
ticketMap.ticket +
'&noncestr=' +
noncestr +
'×tamp=' +
timestamp +
'&url=' +
url
),
};
}
return sig;
}