当请求遇到diskCache

1,713 阅读2分钟

写在前面

探讨这个问题源于客户反映的一个bug。业务场景是这样的:

当前页面有一个列表,列表有很多行数据,某一些数据链接着第三方页面,点击后页面跳转到第三方的链接,用户在此基础上对数据进行一些增删改的操作。操作完了后,按浏览器的返回键返回到当前页,此时数据没有刷新。

按理说,不应该呀,我在页面载入时,也就是vue的created生命周期里,就请求了接口,无论如何,数据应该是更新了的。于是打开network重复了一遍客户的操作,发现了接口请求虽然是200,但后面跟了一行灰色的字disk cache

下文会探讨这个问题为什么会出现,以及出现导致了什么问题,并给出了几种禁止缓存的方案。

如何遇到

  • 第N次打开网页
  • 从第三方页面返回

这是由于浏览器缓存,浏览器缓存不止disk cache一种,可以通过这篇文章来理解。

导致了什么问题

既然浏览器有了这些资源的缓存,页面再次请求这些资源的时候,就会直接从缓存里取而不会请求服务器。也就是说,如果服务器在这段时间更新了这些资源,就不能及时反应在页面上。

动图在这里:

缓存1.gif

怎么解决

眼不见为净法(手动清除缓存)

F12->Network->勾选Disable cache

或者浏览器的设置->安全检查->清除浏览数据

但是,这方法,只在你的浏览器上有效。除非你可以用脑电波控制客户和你做同样的操作,所以其实没什么用。

主动禁止法(请求设置)

  • no-cache

    如果用的是fetch

    fetch("http://localhost:3115/api/test", {
            cache: "no-cache"
          }).then(response => {
            console.log(response);
          });
    
  • 传一个没用但不重复的参数

    如果用的是axios

    //interceptors.request.use内
    config.params = { ...config.params, nocacheNum: Date.now() }
    

自暴自弃法(强制刷新页面)

利用从第三方页面返回后window.performance.navigation.type的值进行页面刷新。

关于这个API的具体介绍可以在MDN搜索PerformanceNavigation

通过路由切换进入的其他页面(如上面动图从Home进入到About页面)时,type的值是0;

在当前页面刷新后,type的值是1;

从历史记录、前进后退访问时,type的值是2;

if (window.performance.navigation.type === 2) {
      location.reload()
}

服务器配置禁止缓存

以Node为例

const server = http.createServer((req, res) => {
    res.writeHead(200, {
        "Access-Control-Allow-Origin": "*",
        "Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
  });
})