坑:在使用react + umi框架做前端开发,使用express框架部署服务的时候,遇到index.html被缓存,导致页面不更新,需要强制刷新或清除缓存。
(以前大哥留下的坑,一直没被解决,吐血。。。。。。)解决方案在最后
1、网上比较多的解决方案(但没解决我的问题)
设置index.html 的meta标签,禁用缓存,如下:
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="0" />
2、在index.html设置了meta标签并没有啥卵用,最后发现在请求时候的响应头里边不对,如下:
应该是在express服务中header设置了缓存。
坑在这里,访问页面路径时响应头中设置了缓存,导致浏览器再次访问目标页面路径时,直接不会去请求服务器(该请求被通知浏览器缓存)。
比如:我的路由路径是:xxx/app/detail,实际上加载的文件是index.html,虽然index.html设置了meta不缓存,但是浏览器被通知了xxxx/app/detail这个请求被缓存,不需要重新向服务器请求,导致index.html中的meta标签没啥卵用。
3、通过查阅express禁用缓存的博客,在express中,托管静态资源时,做了缓存设置
app.use(express.static(path.join(__dirname, 'public')),{maxage:7 * 24 * 60 * 60 * 1000});
意思就是public目录下的静态资源都启用缓存,缓存时间为7 * 24 * 60 * 60 * 1000。
查阅到的解决方案:
请求根路径时,设置响应头不缓存。然而很多时候,用户并不是去请求根路径,是带了路由的,比如:xxxxx/detail 这个时候这里就没作用了。
注意:不能直接设置全部的响应头,会影响到其它静态资源的缓存
app.use(function (req, res, next) {
if(req.url == '/'){
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Expires', '0');
}
next();
});
最后终于解决问题:
在托管静态资源的时候,单独对index.html 的资源设置不缓存。
app.use(express.static(path.join(__dirname, 'public'), {
maxage: 7 * 24 * 60 * 60 * 1000, setHeaders: (res, path, stat) => {
// 设置/index.html 不缓存
if (res.req.url === '/index.html') {
res.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate');
res.setHeader('Pragma', 'no-cache');
res.setHeader('Expires', '0');
console.log('index set no-cache success!!!')
}
}
}));
setHeaders方法:
在响应中设置自定义标头的功能。对标头的更改需要同步发生。该函数被称为fn(res, path, stat),其中参数是:
res响应对象
path正在发送的文件路径
stat正在发送的文件的 stat 对象
最后,express.static 方法是基于serve-static的
另附:HTTP 缓存机制