概述
项目架构
使用Vue+Vue-router
问题描述
- 在 iPhone 中的微信APP中,打开初始页面 A,然后由 A 页面进入 B 页面
- 在 B 页面打开微信右上角菜单,使用“复制链接”功能
- 最后粘贴出来的链接是 A 页面的链接
原因分析
根据 GitHub 有 weui 的这篇 issue,出现这个问题的原因,是因为微信内置浏览器对history
的支持不够全面,导致对于开启了 History Mode 的 SPA 应用,只会保存第一条 url。
而解决方法,则是在打开每个页面时刷新一次,更新当前的history
。
解决方案
思路
由于项目中我们使用的Vue-router
,所以可以通过路由守卫,在每次跳转时给URL
添加一个随机参数wxr
,然后刷新页面。在判断到当前URL
存在该参数时,则加载页面,避免重复刷新。
此外,在打开页面后,需要将url
还原为正常的地址。
具体实现
根据上述的思路,我们在路由守卫beforeEach
,添加判断,若跳转链接非初始页面,且参数wxr
不存在,则添加参数wxr
,并且通过next
函数跳转到新的页面。
注:此逻辑中未进行页面重新加载。
/**
* 在链接后加一个随机参数 wxr,以解决 ios 复制链接的问题
* @param {*} to
*/
function wxRefresh(to) {
const newTo = Object.assign({}, to);
newTo.query = Object.assign({}, to.query);
newTo.query.wxr = `${new Date().getTime()}`;
return newTo;
}
router.beforeEach((to, from, next) => {
if (from.fullPath !== '/' && !to.query.wxr) {
next(wxRefresh(to));
} else {
next();
}
});
在路由守卫beforeEach
,若当前链接存在参数wxr
,则将url
还原为正常的地址,并重新加载页面。
/**
* 去除链接后的随机参数 wxr,以解决 ios 复制链接的问题
* @param {*} to
*/
function wxDelRefresh(to) {
let url = `${window.location.protocol}//${window.location.host}/XXXX{to.fullPath}`;
const reg = /&wxr=/.test(url) ? /&wxr=[0-9]{13}/g : /\?wxr=[0-9]{13}/g;
url = url.replace(reg, '');
window.location.replace(url);
}
router.afterEach((to) => {
if (to.query.wxr) {
wxDelRefresh(to);
}
});
这里我们使用window.location.replace()
来重新加载页面,是因为该方法可用一个新文档取代当前文档,并且不会在 History 对象中生成一个新的记录。这样可以避免加载页面后,在微信中点击返回跳转链接错误的问题。
参考链接
- iphone 上微信的“复制链接”功能复制出来的是修改前的链接,by Wise.Wrong