-
Notifications
You must be signed in to change notification settings - Fork 6
跳过微信内置浏览器缓存 #38
Description
Updated at 2020年03月11日:
今天又研究了一下如何跳过缓存,因为一个在线教材的业务在不断更新各个图书的内容,但是有用户反映没有看到更新后的内容。
做了如下设置,等用户反馈:
- IIS 中,指定路径的 HTTP 响应头添加如下标志:
Cache-Control: no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0
- HTML 页面中,head 块添加如下代码:
<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" />参考链接:
- https://stackoverflow.com/questions/1341089/using-meta-tags-to-turn-off-caching-in-all-browsers
- https://stackoverflow.com/questions/49547/how-do-we-control-web-page-caching-across-all-browsers
- IIS 中,指定路径的“输出缓存”配置中,禁用特定类型文件的缓存:
参考链接:
Updated at 2019年8月15日:
今天在调试一个后端程序,发现在 Express.js 里设置了 HTTP 响应头来禁用缓存的话,前端页面调用的 API 就不会被缓存,每次都必定向后端发起请求,并且 HTTP 响应的状态码始终为 200,开心!哈哈。这么说,会被微信缓存的这些页面,可以通过 Express.js 来渲染?然后设置 HTTP 响应头来禁用缓存,这样就不担心微信和 QQ 的缓存问题了?可以试试。
PS:在 IIS 设置同样的 HTTP 响应头,是起不到作用的,必须得在 Express.js 里设置才行。
Updated at 2019年3月25日:
刚才在微信中测试页面,发现页面所加载的 CSS 样式是被缓存过的,也就是说即使设置了 HTTP Header 的 Cache-Control 字段为 no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0,也依然可能不生效?那就闹心了……那还是得用 window.location = xxx.html?v=Math.random() 这种方法来保证始终访问的是最新的页面,当然了,目标页面也需要用 Webpack 之类的工具来打包,给资源文件名加上 hashtag,来保证用户始终看到的是最新的资源。
Updated at 2019年03月09日:
问了问大神,尝试在 Nginx / IIS 中设置 HTTP Header 的 Cache-Control 字段为 no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0,终于实现禁用缓存的需求了,超级开心!而且之前在网页中设置 meta 属性的方法不管用,是因为这样设置之后,只能控制网页所加载的其他静态资源的缓存设置,无法控制网页本身的缓存设置,所以还是得从 Nginx / IIS 上面入手。
Updated at 2018年11月19日:
上网查了一圈,好像还是只能用 window.location = xxx.html?v=Math.random() 的方法,跳转到新页面,来变相地跳过微信内置浏览器的缓存。
需求描述
微信默认会缓存网页及相关资源,网页一旦更新,用户扫码后还需手动刷新一下,才能看到更新后的页面,否则就只能看到旧页面,这个问题如何解决?
方案调研
参考资料:
- Disable nginx cache for JavaScript files
- Cache-Control - HTTP | MDN
- 我想转行之----微信浏览器缓存:作者介绍了自己踩过的各种坑,值得借鉴
- 怎样禁止微信内置浏览器的缓存?
- 被微信浏览器的缓存给忽悠啦!
- 微信浏览器取消缓存的方法
测试记录
应用层
自己的手机
- iPhone 7
- iOS 12.1.4
- 自用流量
- IIS 各级目录按照默认设置启用了缓存
- 未在 HTTP 响应头中禁用缓存
- 代码层面也未操作缓存
| 类型 | 缓存 | 具体操作 |
|---|---|---|
| HTML | 是 | 更改 HTML 页面内容,微信再次扫码,显示的还是旧页面 |
| JS | 否 | 更改 HTML 所引用的外部 JS 文件的内容,微信再次扫码,就会加载新的 JS |
| CSS | 否 | 更改 HTML 所引用的外部 CSS 文件的内容,微信再次扫码,就会加载新的 CSS |
| IMG | 是 | img 标签中的 src 不变,实际图片更改之后,微信再次扫码,显示的是旧图片 |
老刘的手机
- iPhone 6
- iOS 9.1
- WiFi
- IIS 各级目录按照默认设置启用了缓存
- 未在 HTTP 响应头中禁用缓存
- 代码层面也未操作缓存
| 类型 | 缓存 | 具体操作 |
|---|---|---|
| HTML | 是 | 更改 HTML 页面内容,微信再次扫码,显示的还是旧页面 |
| JS | 否 | 更改 HTML 所引用的外部 JS 文件的内容,微信再次扫码,就会加载新的 JS |
| CSS | 否 | 更改 HTML 所引用的外部 CSS 文件的内容,微信再次扫码,就会加载新的 CSS |
| IMG | 是 | img 标签中的 src 不变,实际图片更改之后,微信再次扫码,显示的是旧图片 |
朱姐的手机
- OPPO A57t
- Android 6.0
- WiFi
- IIS 各级目录按照默认设置启用了缓存
- 在 HTTP 响应头中禁用缓存
| 类型 | 缓存 | 具体操作 |
|---|---|---|
| HTML | 否 | 更改 HTML 页面内容,微信再次扫码,显示的还是旧页面 |
| JS | 否 | 更改 HTML 所引用的外部 JS 文件的内容,微信再次扫码,就会加载新的 JS |
| CSS | 否 | 更改 HTML 所引用的外部 CSS 文件的内容,微信再次扫码,就会加载新的 CSS |
| IMG | 否 | img 标签中的 src 不变,实际图片更改之后,微信再次扫码,显示的是旧图片 |
会话层
已经在微信中扫码访问过的页面,用 IIS 的 URL 重写功能,将这个页面的请求重写到百度首页,微信再次扫码访问该页面,依然显示旧页面,说明请求就没有到后端。
应用过程
无效方案
上面这个链接里,讲的各种设置 HTML meta 属性的方法,在 iOS 中全部无效。
有效方案
后端(ExpressJS)
参考 How to disable webpage caching in ExpressJS + NodeJS? 这篇文章,在 app.js 中全局设置 HTTP 响应头的 Cache-Control 字段,在全站范围内禁用缓存。
服务端(Nginx / IIS)
在 Nginx / IIS 中设置 HTTP Header 的 Cache-Control 字段为 no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0,就可以禁用微信内置浏览器的缓存功能了。不过这个应当只用在图书配套资源的页面上。
另外还需要研究一下,微信内置浏览器的缓存多久才会过期。反正四五分钟内连续多次扫描同一个二维码,是不会过期的。
设置跳转页
参考资料的后两个链接,讲的都是将用户扫描后所访问的初始页面设置为中转页面,在页面中用 window.location = xxx.html?v=Math.random() 这种方式跳转到目标页面,这样可以保证用户总能看到最新的页面。
然后还需要用 Webpack、Parcel 这样的工具,更新 HTML 页面所引用的静态文件,这样才能保证整个网页都是最新版的。
PS:如果源页面和目标跳转页面在同一个目录中,则 window.location = xxx.html?v=Math.random() 这里,直接写 HTML 页面的文件名即可,不需要再加上路径。
过程记录
MDN搜索header cache no-store
发请求的时候明确告诉服务器,不要缓存
应用层的问题不要飘移到下层
做实验可以,但不是你的解决方案
这是在应用层的东西,不要放到你的会话层来处理
再说明确点,这个问题应该在你的代码里来解决,而不是在你的web server
你的代码就要告诉微信,我不要你缓存
加随机参数也行,一般是对付cdn的,有标准方法,我觉得cache no-store好些
越底层越克制
看看http协议吧
这话我跟你说了好多次了
白瞎了这么好的脑子了
你下回肯定会在header里加很多东西,请克制
RFC
英文好,就看这,别的野鸡书看了也是浪费时间
http协议几乎是最好懂的协议了
都看,先看数字小的
这文档会指引你看相关东西的
你其实可以每天看一篇
