小程序 Web-view页面中使用微信api
1. 前言(直接看步骤请翻到第4)
最近公司有个新的需求,就是把之前通过H5开发的功能,通过web-view移到小程序上,其中涉及到了调用微信的相机,相册等功能,需要使用JSSDK,网上看了许多帖子,踩过不少坑,最后才成功的,下面以通过nestjs,复述一下步骤以及注意点
2. 前期准备
- 微信公众号(是的你没有看错),要有管理员权限
- 小程序(废话),要有管理员权限
- 微信官方文档
- 编写加密算法的后台
- 一个在小程序业务域名以内的网页
3. 疑惑点
-
为什么明明是小程序中引用jssdk,却需要微信公众号?
其实很多人(包括我),几乎所有步骤都是照着文档走的,包括加密算法,通过测试也是对的,
但是最终就是不出效果,其实问题很可能出现在这里。
让我们先打开JSSDK说明文档,
仔细阅读一下,会发现JSSDK本身其实就是公众号的功能,所以他的参数自然是需要公众号的参数了 -
那我用公众号怎么保证我的小程序是可以用的呢
公众号有个关联小程序的功能,而小程序的web-view的设置就是可以打开关联公众号的内容 -
如果我不是原生微信开发,使用会有什么不同吗
我是用的是uniapp开发的小程序,因为没有考虑到其他平台的兼容性,在web-view内嵌的页面中完全是用的原生的api,如果要兼容其他平台我只能说,对不起我也不知道了。。。
4. 具体步骤
- 打开微信公众号的开发者后台,拿到公众号的APPID 和 AppSecret,在开发管理下的基本配置中,需要注意的是 AppSecret生成后是不会在页面展示的,需要用户自己保存,如果遗忘了,需要重置。
- 为公众号添加关联小程序,需要小程序管理员扫码
- 为公众号添加ip白名单和JS域名白名单
注意域名白名单不要加上https之类的东西,他需要的是域名
- 编写获取加密签名的后台代码。
这里使用了nestjs,nodejs其实是一个思路,只留下了主要代码。
wehcat-mini.service.ts
import { Injectable } from '@nestjs/common';
import axios from 'axios'
import * as c from 'crypto'
// 加密的库
import NodeCache = require('node-cache');
// 需要用node-cache做缓存,因为微信接口对调用次数有限制的
@Injectable()
export class WechatMiniService {
private App_Id = '这里是appid'
//公众号的APPID,隐私起见改掉了
private App_Scret = '这里是App_Scret '
//公众号的App_Scret ,隐私起见改掉了
private noncestr = 'abac'
// 随机字符串,其实随便写也可以不过要保证,前端和后台一致,所以这里写死了
nodeCache = new NodeCache()
TIME = 7000
// 获取AssessToken
async GetAssessToken() {
const Time = 7000
// 缓存事件
let access_token = this.nodeCache.get('access_token');
if(!access_token){
const { data } = await axios.get(`https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${this.App_Id}&secret=${this.App_Scret}`);
this.nodeCache.set('access_token',data.access_token,this.TIME)
access_token = data.access_token
}
return access_token
}
// 获取ticket
async GetJSApiTicket() {
const access_token = await this.GetAssessToken()
let ticket = this.nodeCache.get('ticket')
if(!ticket){
const { data } = await axios.get(`https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=${access_token}&type=jsapi`);
this.nodeCache.set('ticket',data.access_token,this.TIME)
ticket = data.ticket
}
return ticket
}
// 前端访问接口时调用的方法,
async GetSignature(url) {
/* 根据微信的文档,访问对应接口取到对应参数,将所有参数,包括随机字符串,
时间戳等拼接成键值对的字符串,随后进行sha1加密*/
const ticket = await this.GetJSApiTicket()
const { noncestr } = this
let timestamp = parseInt((Date.now() / 1000).toString())
let Str = `jsapi_ticket=${ticket}&noncestr=${noncestr}×tamp=${timestamp}&url=${url}`
let hash = c.createHash('sha1')
hash.update(Str)
// 这里保险起见,我将所有后台调微信api等相关的参数都传给后台了,保证前后端的一致
return { ticket, url, timestamp, md5: hash.digest('hex'), noncestr, app_id: this.App_Id, Str }
}
}
- 小程序的准备
- 将需要嵌入到web-view的页面添加到接口安全域名内
- 将后台接口域名添加到request合法域名中
- 嵌入页面的使用
主要代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.3.2.js">
<!-- 引入js文件 -->
</script>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.min.js"></script>
</head>
<body>
<h2>NPS-ADMIN</h2>
<button onclick="chooseImage()">wechatMini Test</button>
<script>
init()
async function init() {
let { data } = await axios.get('https://njphzh.com:3001/wechatmini/getUser')
console.log(data)
const { timestamp, noncestr, md5 ,app_id} = data
wx.config({
debug: false,//是否开启调试
// 开发者工具中测试可以将其设置为true判断参数哪里出错了
appId: app_id,//小程序appid
timestamp,//时间戳,单位秒
nonceStr: noncestr,//随机字符串
signature: md5,//签名md5
jsApiList: ['startRecord', 'stopRecord', 'playVoice', 'uploadVoice', 'dowmloadVoice', 'onVoiceRecordEnd', 'translateVoice', 'downloadVoice', 'onMenuShareTimeline', 'onMenuShareAppMessage', 'scanQRCode', 'getLocation', 'chooseImage', 'getLocalImgData', 'uploadImage']//当前html需要用到的接口,可在公众号文档中查看
});
}
function chooseImage(){
wx.miniProgram.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
// const tempFilePaths = res.tempFilePaths
console.log(res);
}
})
}
</script>
</body>
</html>
在小程序web-view中内嵌该页面
如果在debug开的时候,输出该消息时,说明配置是正确的,可以使用微信的api了