微信JS-SDK公众平台网页开发大坑硬填
题目
本帖针对微信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
参数ngrok.com/docs/ngrok-…
办法2:(没有测验)
-
本地建立nginx服务器
-
把domain映射到loalhost
-
然后经过nginx的vhosts敞开不同的端口