使用vue-router导航时,Vue SPA会强制重新加载页面

时间:2018-08-22 16:40:09

标签: javascript amazon-s3 vuejs2 amazon-cloudfront vue-router

场景:

我已经准备好替换旧的LAMP网站的Vue2 SPA,但是PO希望逐步部署(仅从一个URL开始)以测试用户的反应,分析,广告收入等。

我们已经建立了此架构以允许这种方法:

Architecture

有效。因此,如果您转到http://example.com/release-first(首先是我们要公开发布的页面),则CF返回S3的内容,并从旧服务器中获取其他任何URL。

但是,当然,当您访问/release-first时,您就进入了SPA,并且由于大多数导航都是通过<router-link :to="">完成的,因此您被困在 SPA,您可以访问新版本的其余部分,这是我们目前不想要的。

我认为可能的解决方案:

一种解决方案是用标准<router-link>链接替换所有<a>标签,这将迫使浏览器每次对CloudFront进行新请求。那可能行得通,但我不想这样做,因为我必须更改很多链接,并且因为链接不是用户可以四处走动的唯一方式(也有一些表单提交等)

所以,我尝试了类似的事情:

router.beforeEach((to, from, next) => {
    if (!/\/release-first\/?$/.test(to.path)) {
        window.location.href = `http://example.com${to.path}`  
        return;
    } else {
        next();
    }
});

这在staging env中可以正常工作(因为它具有不同的子域,因此将其重定向到生产环境),但是如果我在生产环境中尝试,则无法正常工作。我不知道Vue是否劫持了Location API或其他什么,但是它并没有向CloudFront强制提出新的请愿书。

我也尝试过:

const absolutePath = `http://example.com${to.path}`;
window.history.pushState({ urlPath: absolutePath }, "", absolutePath);
window.location.reload();

但是它也不起作用...而且我在vue-router的{​​{3}}中找不到一个选项来强制页面在导航时重新加载。关于如何实现这一目标的任何想法?


评论中要求的其他信息:

  • 路由器模式为history
  • 路径格式如下:
    • /
    • /single-level-pages
    • /two/level-pages
    • /two-levels-with/:param
    • /multiple/level/pages
    • /multiple/level/with/:param/
  • 并非所有路径都共享release-first URL。我想首先发布的URL像first-level-with/an-specific-param
  • 我已经仔细检查了RegExp(并且在那里也使用了console.log)。 CloudFront中的重定向也运行良好。如果在浏览器中输入不同的URL,则可以从Legacy服务器或S3获得内容。我在beforeEach导航卫士中使用的代码也可以在暂存中很好​​地工作,所以唯一的问题是,当域相同时,这是不够的,因为location.href覆盖似乎并没有强制目的地在同一域中时发出新请求。

1 个答案:

答案 0 :(得分:0)

这是我终于解决的方法:

router.beforeEach((to, from, next) => {
    if (
        window.location.host === "prod-env.example.com" &&
        /\/release-first/.test(from.path) &&
        !/\/release-first/.test(to.path)
    ) {
        let a = document.createElement("a");
        a.id = "forceReloadLink";
        a.href = to.path;
        document.querySelector("body").appendChild(a);
        document.getElementById("forceReloadLink").click();
    } else {
        next();
    }
});