单页面应用在IOS微信内置浏览器中的坑

1,317 阅读3分钟

拼团项目自测功能的时候发现了iPhone的一个bug:用户分享到微信的页面在第一次加载,在浏览器中打开后页面是错的

具体流程:在微信中打开分享 -> 授权登录(登录后回到原来的页面) -> 在浏览器中打开 -> 页面错误

由于拼团项目是我司微信商城的子项目,所以它的登录和支付都是依赖微信商城的:

登录流程:检测到用户未登录 -> 存储当前链接,跳转至微信商城 -> 调起登录或获取token -> 回到拼团/token路由 -> /token对应的Token.vue组件会负责将页面重定向到一开始的链接

排查之后发现,单页面应用在微信内置浏览器中只会拿第一次进这个页面的链接,经过验证也确实如此,授权登录后跳转会拼团,虽然页面时对的,但是复制链接却是/token这个路由,于是想办法解决

leader之前遇到过这个坑,所以早就写好了方法:

const source = ...; // 获取当前平台
const flag = sessionStorage.flag;
if (source && source === 'weixin' && !flag) {
  sessionStorage.setItem('flag', true);
  location.href = '...'; // 当前页面的链接
} else if (iflag) {
  sessionStorage.removeItem('flag');
}
// 在检测到当前平台是微信时,页面会重定向一次,为了避免重定向后再次触发刷新,所以要用flag记录一下

在页面中加了这个方法,没有奏效,于是在该页面的子组件中又加了一次,效果就是页面会不定的刷新,说明重定向这个代码是有效的,但是为什么没有效果呢,无奈,只能一行一行的debug,最后发现:

在重定向的下一行写了一个弹窗居然弹出来了!也就是说,重定向失败了!

百度之后发现location.href这种方式会有一定几率失效,是因为微信浏览器拿了缓存。。。

解决的方法很简单,在链接后面加个时间戳就好了:

location.href = '...' + '?time=' + new Date().getTime();

各公司业务不同,希望对看到这篇文章的人有帮助

 

 


8月6日更:

这个问题虽然用上述方法可以解决,但是如果这个页面要调起微信分享的话,就不行了:

分享需要调用wx.config和wx.ready,wx.config需要的数据是我们发送请求,后台返回给我们的,发请求时需要传入你需要分享的链接(shareLink),如果当前页面url和shareLink不同的话,分享出去的就是一个看起来像野鸡页面一样的东西

就像这样,我没有深究原因,不过大概是config配置失败,于是上面的方法必须摒弃。

试了很多种不加参数刷新页面的方法,比如location.reload(true),location.assgin,location.replace等等,发现都没有用,不得不吐槽一句,微信内置浏览器简直就是移动端的IE。。

最终的解决方案是: 时间戳还是要加,在created钩子中再强制去掉,这里用到了history.replaceState方法

beforeCreate(){
    //刷新页面的代码(上述)且加上时间戳,让浏览器不读缓存
}

created(){
    history.replaceState(null, null, '...');
    //第三个参数是你想改成的链接,具体用法百度即可
    //一定要在刷新代码之后执行这句,vue有钩子函数,我就直接写在里面了
    //这个方法可强制改变页面url但是不刷新页面,虽然方法有点投机取巧,但是能解决的问题
}