<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" />
赶巧不巧,正好在假期第一天遇到了修改接口地址的问题 —— 节前最后一个工作日后端兄弟自己修改了编译后的 Js 文件中的接口地址,但是并没有生效,只不过当时没发现,今天电话过来问应该怎么处理,奈何电脑没带在身边,只能让他修改了接口地址之后重新编辑被修改的 Js 文件名中的 hash
值随便改一位,同时修改一下 index.html
中的引入路径。
可是没多久又发来消息说,不行还是请求旧地址,没有被修改。我怀疑是页面被缓存了,于是让他确认了一下页面源代码中是否有 no-cache
的 meta
,他说有,但是页面还是被缓存了,看到引入 Js 文件的路径还是他修改前的旧路径。
于是我就纳闷了,好像浏览器跳过了设置的机制,并没有重新请求服务器获取最新的 index
文件。
正常来说,前端为了加快页面加载,只会在 index.html
页面的 <meta>
中设置 不缓存,而其他类型的资源文件再HTTP服务上设为一个缓存时间,从而加快首屏加载速度。
如果资源文件有变动则通过修改资源文件路径的 hash
值来让浏览器认为是新文件,从而重新请求服务器获取最新的资源。
- 其实都需要在
HTTP Server
上配置缓存策略,这个配置项贴在文章末尾。
所以遇到这个问题的时候我是很懵逼的,我很早之前就已经给 HTML
页面添加上了不缓存的 <meta>
头,当时自测的时候是正常的。就一边翻文档一边写DEMO,不论怎么做都一直复现不了,实在是研究不好了,又问了一下后端兄弟,答:客户使用的微信打开的链接。 ,他暂时先改了一下把页面重定向到了二级目录解决了问题。
所以问题其实是因为微信内置的X5浏览器,马上去微信社区找了一下,果然!一下就找到了,微信公众号页面缓存问题 | 微信开放社区
大概反馈如下:
x5内核好像没有协商缓存
点刷新就访问到新的网页了,第二次进来又是旧的
微信内置的浏览器他不按套路出牌啊,没有协商缓存的同时为了加快访问速度还直接给你缓存了页面。所以之前可能是后端小伙伴没有去配置HTTP服务的不缓存,结果用户访问了页面被缓存起来了。
一般来说服务器端后续把不缓存的配置添加上就好了,结果后期添加上了不缓存的响应头还是没有办法获取到最新的 HTML
入口文件。暂时没有什么好的解决办法了,后端小伙伴已经暂时解决了就先不管了。
🎈 其它问题
1. HTML的 <meta>
标签中设置了不缓存,后端返回头中设置了缓存时间页面会缓存吗?
会被缓存,理论上应该是 Response Headers 的优先级更高。
Meta tags are easy to use, but aren’t very effective. That’s because they’re only honored by a few browser caches, not proxy caches (which almost never read the HTML in the document).
译: meta 标签很容易使用,但并不十分有效。这是因为它们只被少数浏览器的缓存所尊重,而不是代理缓存(几乎从不读取文档中的HTML)。
详情可以参看这个问答 HTML页面 中设置了不缓存,后端返回头中设置了缓存时间页面会缓存吗?
2. HTML的 <meta>
的不缓存设置的应用范围?
HTML
页面中的 <meta>
信息头只会应用在当前 HTML
页面的请求头上,并不会影响 HTML
页面发起的其他 HTTP
请求
✨ Update - 07/03/2024
隔了那么多年,才发现之前的笔记中没有完整的描述好应该如何配置项目的缓存,除了在页面的 meta
头中配置 Cache-Control
(其实并没有多少作用)。
更重要的是在服务器的 HTTP Server
中配置缓存规则。那么,简单的用 Nginx 的配置来举例:
http {
...
server {
listen 80;
listen 443;
server_name localhost;
location / {
root /test/your-dist-path;
# 开启回退路由适配 History 路由模式
try_files $uri $uri/ /index.html;
index index.html index.htm;
# 静态文件配置不缓存
location ~* \.html$ {
add_header Cache-Control no-store;
expires -1;
}
# 资源文件配置缓存72小时
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 72h;
}
}
}
}
最后记得使用 nginx -s reload
让 Nginx 重新加载配置文件(重新加载前程序会自动检测配置文件是否正确,如果有错误会提示并且停止应用新的配置文件)。
参考资源
Cache-Control - HTTP | MDN
HTTP 缓存 - HTTP | MDN
http - How do we control web page caching, across all browsers? - Stack Overflow
google chrome - “Cache-Control: max-age=0, no-cache” but browser bypasses server query (and hits cache)? - Stack Overflow
http - What’s the difference between Cache-Control: max-age=0 and no-cache? - Stack Overflow
http - Difference between no-cache and must-revalidate - Stack Overflow
Cache Control Directives Demystified : Palisade
Caching Tutorial for Web Authors and Webmasters - mnot
浅谈浏览器http的缓存机制 - vajoy - 博客园
理解浏览器缓存机制 [ 没事儿 ]