微信“复制链接”,复制结果为初始页面链接简析

1,423 阅读2分钟

概述

项目架构

使用Vue+Vue-router

问题描述

  1. 在 iPhone 中的微信APP中,打开初始页面 A,然后由 A 页面进入 B 页面
  2. 在 B 页面打开微信右上角菜单,使用“复制链接”功能
  3. 最后粘贴出来的链接是 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 对象中生成一个新的记录。这样可以避免加载页面后,在微信中点击返回跳转链接错误的问题。

参考链接