网页授权的目的是获知浏览页面的人的身份。
网页授权的开发,参照官方文档处理即可。需要注意的地方有
页面跳转回 redirect_uri
如果用户同意授权,页面将跳转至 redirect_uri/?code=CODE&state=STATE。
多了一个 / 符号。前端代码需要对此进行特殊处理。
获取 unionid
用户统一标识(针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的),只有当scope为"snsapi_userinfo"时返回
当开发者在网页中在不规范使用发起 snsapi_userinfo 网页授权时,微信将默认打开网页快照页模式进行基础浏览。
为了避免进入快照页模式,在用户打开网页时,只能进行 scope=snsapi_base 的静默授权。在获取用户头像和昵称时,顺便获取到 unionid,再更新用户信息。
微信支付
微信支付下单前需获取到用户的 openid,因此必须先完成 snsapi_base 网页授权。微信支付不需要引入 JS-SDK,因为它直接使用 WeixinJSBridge.invoke 调起收银台,并且具备自己的签名机制。
JS-SDK
JS-SDK 封装了 WeixinJSBridge,使用之前需要签名。主要的用途是控制是否允许网页被分享,以及分享的标题、图标、描述。参照官方文档开发,需要注意的地方有
页面 URL 错误
在路由模式为 history 模式时,iOS 需要使用第一次进入页面的 URL 获取签名,安卓每次路由切换都重新配置签名。官方文档 iOS WKWebview网页开发适配指南的说明太简略。实际上,用以下代码即可同时兼容 iOS 和 Android
// iOS中保存落地页url为authUrl!
let authUrl: string | null = null;
/**
* 获取微信JS-SDK使用权限签名算法所需的当前网页URL,不包含#及其后面部分
*/
export function getAuthUrl() {
const url = getCurrentUrl();
if (!authUrl) {
authUrl = url;
}
return window.__wxjs_is_wkwebview ? authUrl : url;
}
注:getCurrentUrl
见下节说明
URL 参数带中文或者特殊字符
注意不能像官方文档-附录5-常见错误及解决方法中说的那样,直接用 window.location.href.split('#')[0]
获取当前页面的 URL
/**
* 获取当前网页URL,不包含#及其后面部分,会自动对参数值进行编码。
*/
export function getCurrentUrl() {
const { protocol, hostname, port, pathname, searchParams } = new URL(window.location.href);
const params: { key: string; value: string }[] = [];
searchParams.forEach((value, key) => {
params.push({ key, value });
});
const search = params
.map(({ key, value }) => {
value = isEncoded(value) ? value : encodeURIComponent(value);
return `${key}=${value}`;
})
.join('&');
return protocol + '//' + hostname + (port ? ':' + port : '') + pathname + (search ? '?' + search : '');
}
function isEncoded(uri: string) {
uri = uri || '';
try {
return uri !== decodeURIComponent(uri);
} catch {
return false;
}
}
按以上方式,对于变化 url 的 SPA 的 web app 就可在每次 url 变化时进行调用 wx.config 而无需关注 OS 的差异了。
iOS wx.config 的时序问题
真机实测中,发现 iOS SPA 应用在换页时,wx.ready 会先于 wx.config 调用。推测原因是 iOS 的 authUrl 在换页时并未发生变化,因此 wx.config 的调用是不必要的,微信浏览器会当其已经成功,直接执行 wx.ready 里的代码。
解决方案是将所有可能会用到的微信JS接口都放一起,每个 wx.config 都使用这个 jsApiList 而不是页面在初始化的时候单独去指定自己要用的 jsApiList。
调试诀窍
- 出现 config:invalid signature,同时给出了 realAuthUrl,则这个 realAuthUrl 就是正确签名所需要的 url。通过对比我们代码里传入的 authUrl 和提示的 realAuthUrl 就能找出问题。
- 出现 the permission value is offline verifying,则原因一般是调用的 JSAPI 没有传入 config 的 jsApiList 参数中
网上有价值的参考文档有:
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。