付费节点推荐
免费节点
节点使用教程
题目
本帖针对微信JSSDK网页开发中碰到的坑,讲述填坑过程。
官网: developers.weixin.qq.com/doc/offiacc…
流程
步骤一:获取公众号的access_token准备工作
目的:正如所有公开平台,都需要注册并获取appID和appSecret,以便你开发的“app”可以访问该公众号的资源(公众号不一定是你所有,可以是的客户的,只要提供appID和appSecret即可)
方法:获取公众号的appID和appSecret,并设置你的服务器的ip地址(如果本地开发,则用本机IP:百度搜索ip即可)
步骤二:设置你的网页的domain
目的:白名单你的域名,这样你的网页比如http(s)://domain.com/page.index 就可以调用JS-SDK来获取微信平台/app暴露给你的功能,比如拍照,录音,支付等原生的H5没有的功能,可以把JSSDK看成是一个桥接器。
为什么要这样?你可能有这样的疑问。确实,类似的开发平台有时候设置很麻烦,容易让人摸不着头脑。为了快速理清思路,我一般会这么想:如果我是平台方,我会怎么做?所以,如果你是微信方,你会不会想:虽然我有接口让开发者动态提供url并给他返回签名,见签名文档,但是这个url我没有做任何限制,会不会有安全隐患,就算没有安全隐患也要管控吧?所以,要提供白名单功能。
方法:如图,输入根域名和www次域名(不一定要输入,这个不一定,没有测试)
条件:
- 域名需要icp
- 用txt文件验证域名所有权
我的操作,方法1:
- 在linux部署nginx(腾讯服务器,因为好像icp备案完成后也需要指向一个服务器)
- 设置nginx(大概如下)
server {
root /var/www/domain.com;
index index.html index.htm;
server_name www.domain.com domain.com;
location / {
try_files $uri $uri/ /index.html?/$request_uri;
}
}
复制代码
- 部署certbot添加https
- 把txt文件放入 /var/www/domain.com
- 公众号验证成功
另外一个方法2(没有测试):
- 免费获取阿里云或者腾讯云的证书(免费的不是通配符,比如可以是www.domain.com)
- 开通腾讯云COS或者阿里的OSS,把文件夹绑定到域名上面(通过CDN)
- 把txt文件放到OSS或者COS上面
- 公众号认证
结论:
- 公众号txt认证,似乎认证不需要https协议,http即可(除非你用的是方法2,因为CDN需要https)
- 白名单后,测试网页域名似乎不需要https(测试http可以)
- 白名单根域名后(domain.com)后,测试网页似乎可以是其他次域名,比如ngrok.domain.com
第2,3结论,请继续看。
步骤三:服务器获取signature
目的:服务器(步骤一,白名单的IP)从微信拿到签名
import cache from 'memory-cache';
import sha1 from 'sha1';
import config from '../config';
import { axiosGet } from './util';
export default function (url: string) {
return new Promise((resolve, reject) => {
const noncestr = config.wechat.noncestr;
const timestamp = Math.floor(Date.now() / 1000); //精确到秒
if (cache.get('ticket')) {
console.log('get wechat ticket from memory cache...success');
const jsapi_ticket = cache.get('ticket');
return resolve({
openTagList: "wx-open-launch-weapp",
appId: config.wechat.appid,
nonceStr: noncestr,
timestamp: timestamp,
url: url,
jsapi_ticket: jsapi_ticket,
signature: sha1('jsapi_ticket=' + jsapi_ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url)
});
}
console.log('ticket expired, refetching token and ticket...');
axiosGet(config.wechat.accessTokenUrl, {
grant_type: config.wechat.grant_type,
appid: config.wechat.appid,
secret: config.wechat.secret
}).then(res => {
const accessToken = res.data.access_token;
axiosGet(config.wechat.ticketUrl, {
access_token: accessToken,
type: 'jsapi',
}).then(res => {
const ticket = res.data.ticket;
cache.put('ticket', ticket, config.wechat.cache_duration);
resolve({
appId: config.wechat.appid,
openTagList: "wx-open-launch-weapp",
nonceStr: noncestr,
timestamp: timestamp,
url: url,
jsapi_ticket: ticket,
signature: sha1('jsapi_ticket=' + ticket + '&noncestr=' + noncestr + '×tamp=' + timestamp + '&url=' + url)
});
}).catch(err => {
reject(err);
});
});
});
}
//util
export const axiosGet = async <T>(baseUrl: string, params: T) : Promise <any> => {
try {
return await axios.get(baseUrl, {
params
});
}catch (e) {
console.log(e);
}
};
复制代码
结论:
- 先获取access_token (微信设置两小时过期,见官网)
- 然后换取js_ticket (微信设置两小时过期,见官网)
- 自己设置缓存,防止反复请求微信造成拒绝
步骤四:本地开发网页H5并调取JSSDK
目的:开发前端
方法: 用微信开发者工具IDE开发(用浏览器调用JSSDK没有反应,因为不是微信模拟环境)
问题来啦:如果你用本地开发localhost在IDE中会无法访问接口,错误如下:
- localhost,在微信开发者工具中调试时报以下错误:
xxxx:fail, the permission value is offline verifying
蹩脚的英语的意思是:网页为离线网页,即没有在服务器上。
步骤五:填补大坑
目的:把认证的域名domain.com映射到本地localhost,解决如上问题。问题的根源是,似乎IDE在夹在JSSDK的时候,会把当前的url传递到微信后端,并核对是否是认证的域名,如果不是则报错。
方法:首先讲,这个开发非常不友好。
- 开发不可能把网页放到真实服务器上开发,几乎是自杀式开发
- 微信为啥不能白名单localhost,给程序员提供一个友好的开发环境
- 微信为啥不能提供一个沙箱测试appID来放开localhost限制
既然,没有这样的环境,只能想办法自己解决。
基本思路:把认证的域名映射到本地localhost,然后在IDE输入域名,欺骗微信IDE,即:domain.com -> localhost
方法1(macos):
- 编辑hosts文件
$ sudo nano /etc/hosts
- 映射domain到localhost
localhost www.domain.com
- 测试
ping www.domain.com
- 用www.domain.com开发,结果发现失败。 因为代码放在localhost 3000端口上。默认的localhost在80端口。
- 需要把代码加载到80端口,比如用reactjs的话是
sudo PORT=80 react-scripts start
注意:80端口小于1024,所以需要sudo权限
如何把domain映射到任意的localhost的端口呢?
方法1:
- 购买ngrok的服务ngrok.com,大概是25美金pro版
- 把domain域名绑定到ngrok, 设置CNAME进行绑定比如:ngrok.domain.com(不影响你现有的www.domain.com访问互联网,CNAME设置也只是影响ngrok次域名)
- 下载ngrok,并运行
$ ./ngrok http --hostname=ngrok.domain.com 3000
- 成功
⚠️注意:ngrok的设置方法和config文件如下
⚠️注意:在wechat的IDE上面如果你输入 ngrok.domain.com的话,访问本地服务器可能会有跨域错误,所以要用https
nano .ngrok2/ngrok.yml
方法2:(没有测试)
- 本地搭建nginx服务器
- 把domain映射到loalhost
- 然后通过nginx的vhosts开放不同的端口
作者:Frank同志68687
链接:https://juejin.cn/post/7089708889515507725
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
未经允许不得转载:Bcoder资源网 » 微信JS-SDK公众平台网页开发大坑硬填