如何保证 HTTP 强制缓存的新鲜度

2022-10-26 10:36:50 +08:00
 lete

很多时候,我们的网站上都会对静态资源开启 HTTP 缓存,HTTP 缓存分为两种,但对于静态资源来说,我想,大部分人开的因该是强制缓存吧?

不过强制缓存有个缺点那就是没法保证资源的 新鲜度(最新的) ,只能等待缓存时间过期才能获取到最新的资源内容

于是我写了一个库 Cache-Hash 在线求 star✨ ,专门处理 HTTP 缓存破除的

我的博客已经用上了: https://blog.imlete.cn

原理

通过给网站引入的资源,打上 hash 版本号,一旦内容改变,hash 会随着改变,这样即可通过改变 url 地址来破除缓存,能够保证网站所引用的资源是最新的

例如以下形式

<script src="https://demo.com/js/main.js?v=5e74b42bf5"></script>

使用方式

可以通过使用 CLI (命令行工具) ,也可以使用 JavaScript API 来对静态资源的引用生成 hash

可以全局安装使用

npm install cache-hash -g

cache-hash --target source --output public

# 简写

cache-hash -t source -o public

如果你不想全局安装,可以使用 npx

npx cache-hash --target source --output public

它是如何工作的?

它通过读取你给定的 target 目录,检测目录内的所有 html 、css 、js ,并对这些文件生成 AST(Abstract Syntax Tree) 即抽象语法树 ,之后通过修改 ast 语法树的内容后,再通过 ast 语法树编译回源代码即可

5975 次点击
所在节点    Node.js
33 条回复
3dwelcome
2022-10-26 16:40:47 +08:00
@lete 我原贴的意思是,如果浏览器直接读 html 里的 etag 或者 last-modifed-time ,就可以不协商,仅仅本地对比。

现在浏览器没读,所以就只能发请求服务器进行协商。

@yushiro 早期的手机浏览器设计很奇葩,会自作主张在 url 请求后面加?作为一些特殊标识。然后服务器收到两个?的参数,就会出问题了。
lete
2022-10-26 16:45:38 +08:00
@3dwelcome 哦哦,是我没看明白,哈哈哈

不过 w3c 没制定标准,浏览器厂商是不可能去做的,况且如果有浏览器厂商做了,其它厂商也不一定做
lete
2022-10-26 16:49:17 +08:00
@yushiro 确实有些浏览器或套壳浏览器有这种问题
liaohongxing
2022-10-26 16:57:40 +08:00
vue-cli vite-cli nuxt-cli cra-cli nextjs-cli build 出来文件都自带 hash , 一般都是 index.html 设置 no-store 。index.html 里面引用的 js css images 跟着自动变 。感觉现在都用这种脚手架了吧
CodingNaux
2022-10-26 17:02:34 +08:00
这种常见问题,应该都有方案
iqoo
2022-10-26 20:07:10 +08:00
这方案十几年前就普遍使用了
learningman
2022-10-27 01:35:48 +08:00
有的 CDN ignore query string 的,你这白操作
lete
2022-10-27 09:15:27 +08:00
@learningman 你可能理解错了,query string 主要是给浏览器辨别这个连接有没有缓存的,如果 url 变了就会像服务器索要新的资源,没变就直接充浏览器缓存中读取
learningman
2022-10-27 09:20:01 +08:00
@lete #28 你改 query string 刷了浏览器的缓存,但是 CDN 的缓存还是可能没刷啊。。。不如乖乖配 Cache Control
lete
2022-10-27 09:40:07 +08:00
@learningman 不设置 CDN 的缓存不就可以了,直接 Cache-Control 设置强制缓存
humbass
2022-11-05 00:00:48 +08:00
我的天啊,真是这么玩的吗 ?如果是 HTML 的变化,一般前段打包器就已经做了这个工作,比如 webpack ,只要打包内部的索引( hash )就自动换了。

难道我理解错了 楼主 的意思吗
whatFoxSay
2023-02-07 17:55:44 +08:00
这不就是协商缓存吗。。。
lete
2023-02-11 16:08:48 +08:00
@whatFoxSay 不是协商缓存呀

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/889921

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX