头图

网页授权的目的是获知浏览页面的人的身份。

网页授权的开发,参照官方文档处理即可。需要注意的地方有

页面跳转回 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。

调试诀窍

  1. 出现 config:invalid signature,同时给出了 realAuthUrl,则这个 realAuthUrl 就是正确签名所需要的 url。通过对比我们代码里传入的 authUrl 和提示的 realAuthUrl 就能找出问题。
  2. 出现 the permission value is offline verifying,则原因一般是调用的 JSAPI 没有传入 config 的 jsApiList 参数中

网上有价值的参考文档有:

  1. 微信分享网址后显示标题、描述和logo图片
  2. 自定义分享的实现

黄灏
4 声望0 粉丝

一个技术爱好者。