写在前面
探讨这个问题源于客户反映的一个bug。业务场景是这样的:
当前页面有一个列表,列表有很多行数据,某一些数据链接着第三方页面,点击后页面跳转到第三方的链接,用户在此基础上对数据进行一些增删改的操作。操作完了后,按浏览器的返回键返回到当前页,此时数据没有刷新。
按理说,不应该呀,我在页面载入时,也就是vue的created生命周期里,就请求了接口,无论如何,数据应该是更新了的。于是打开network重复了一遍客户的操作,发现了接口请求虽然是200,但后面跟了一行灰色的字disk cache
下文会探讨这个问题为什么会出现,以及出现导致了什么问题,并给出了几种禁止缓存的方案。
如何遇到
- 第N次打开网页
- 从第三方页面返回
这是由于浏览器缓存,浏览器缓存不止disk cache一种,可以通过这篇文章来理解。
导致了什么问题
既然浏览器有了这些资源的缓存,页面再次请求这些资源的时候,就会直接从缓存里取而不会请求服务器。也就是说,如果服务器在这段时间更新了这些资源,就不能及时反应在页面上。
动图在这里:
怎么解决
眼不见为净法(手动清除缓存)
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",
});
})