新手问题 Turbolinks 会导致微信网页在 iOS 上点击链接时出现 invalid signature 错误,Android 和开发者工具则正常

imwildcat · 2017年06月20日 · 最后由 imwildcat 回复于 2018年02月09日 · 4457 次阅读

最近在做微信网页开发,用的是 wechat 这个 gem。 iOS 上,目前生成的网页,首页没问题,一旦点击一次链接就会出现 invalid signature 错误。

搜索了很多相关关键词,甚至关于 React 的微信网页开发的。都没找到什么可以利用的资料。 很想用 turbolinks,但是现在看来只能关闭了。奇怪的是为什么 Android 正常 iOS 不正常,按理说 iOS 的浏览器应该更稳定才对。

没细看你的问题,不过大约是这样,wechat 自己的 JSSDK 有一个初始化的方法,在页面加载时进行,turbolinks 下页面切换不会重复触发 ready 的状态,而每次 wechat 初始化的时候用到的 signature 是和当前的 path 有关系的,目测是没有触发 ready 事件所以没有更新新的 signature 造成的…… 如果实在想用 turbolinks 的话试试引入jquery.turbolinks试试。

这是微信 iOS 的浏览器内核切换到 WKWebView 后出现的一个问题,根据官方文档

三:有使用JSSDK,并且使用了wx.config进行权限授权需关注jsapi调用的失败问题 
变化:WKWebview的内部实现变更使我们对微信内的页面jsapi权限管理做了一定逻辑上的调整,有极小可能会发生以前授权正常的jsapi获取权限不正常,从而导致调用jsapi失败。 
适配建议:
1. iOS微信6.5.1,WKWebview在此版本中已知有以下问题:页面使用HTML5的History API pushState; popstate;      replaceState等控制页面导航(典型的如单应用页面),同时使用JSSDK的wx.config为jsapi授权,此时大几率会出现jsapi因为无权限而调用失败的问题。 在6.5.1中页面若可能的情况下,可使用Anchor hash技术替换History技术来解决此问题。
2. iOS微信6.5.2及其之后版本,将不会存在以上问题,但不能100%确认有使用到 history或hash技术更改页面导航地址的页面完全没有此类问题,依然需要开发者注意关注此类问题。

可以考虑在 Turbolink 切换页面的回调里面请求一次 API,从服务器拿到签名参数,并在客户端进行签名操作。(可以借助 wechat gem 里面的一些方法)。下面的代码是我写的一个调用的例子,直接返回给客户端的 JavaScript 进行 eval(可能这样做很 evil),但是能正常跑起来。

def signatuer_js(page_url)
  config_options = {debug: false, api: %w(chooseImage previewImage uploadImage chooseWXPay)}
  js_hash = wechat.jsapi_ticket.signature(page_url)
  return <<-WECHAT_CONFIG_JS
    wx.config({
    debug: #{config_options[:debug]},
    appId: "wechat app id",
    timestamp: "#{js_hash[:timestamp]}",
    nonceStr: "#{js_hash[:noncestr]}",
    signature: "#{js_hash[:signature]}",
    jsApiList: ['#{config_options[:api].join("','")}']
    });
  WECHAT_CONFIG_JS
end
oa414 回复

turbolinks 的回调函数是?

$(document).on('turbolinks:load', function () {

是这个么?我自己尝试过放在这里面,但是似乎还是不行,反而开发者工具都报错了。

cassiuschen 回复

是会触发的,我也不知道为什么。因为看 signature 里面每次都变。

去掉 turbolinks。

Rei 回复

我就是来问如何不去掉的(虽然现在已经去掉了)。

imwildcat 回复

我的微信公众号项目都是用 anchor hash 导航的 SPA,没有用 turbolink,实践上只要在首页进行 JS SDK 的签名就可以。

在需要验证签名的那一个网页,去掉 turbolink

这个问题不难,可以解决方法如下:

  1. 将加密过程放在具体每页的 body 中的 script 中。

  2. 关闭这个页面的 turbolinks cache, 避免前进后退导致的 script 执行问题。

    meta name="turbolinks-cache-control" content="no-cache"

  3. 保险手段 ( 可选 ), 将其他页面链接到该页时,关闭 turbolinks.

link_to xx_path, data: { turbolinks: false }

具体的原因可以参考我之前写的 turbolinks5 的原理解析:http://yafeilee.me/blogs/88

lyfi2003 回复

感谢!

现在的加密过程也是在页面的 script 中,但是很多异常表现,也很难 debug

wechat 这个 gem 有 wechat_config_js 这个 helper 方法 调用也很简单

= wechat_config_js(debug: false, api: [...])
steven_lv 回复

但是用这个 method 一样需要停用 turbolinks

需要 登录 后方可回复, 如果你还没有账号请 注册新账号