HTTP缓存
怎么说呢, 去年折腾了一段时间sw缓存, 实在有点折磨. 原因主要是错误地把index.html和/给缓存了, 导致获取的一直是旧资源. 最近陆陆续续把sw缓存都删了, 最后决定加个HTTP缓存.
HTTP缓存的优势
HTTP缓存跟sw相比有一个很明显的优势, HTTP缓存特别简单, 只需要简单地配置响应头就可以了. 在现代化的构建工具下, 服务端几乎不需要检查资源有没有过期, 只需要检查自己有没有这个资源就可以了.
不知道大家有没有观察过vue项目或者vitepress博客打包后的产物, 应该可以看到xxx.BBSDLKJ.js之类的东西. 这中间的值其实相当于一个标识符, 每一次构建基本都不一样. 因此服务端只需要检查这个东西在不在自己对应的路径上, 如果在的话说明浏览器缓存的这个就是最新的, 如果不在的话返回给浏览器就可以了.
所以像我们这种用vite构建的静态博客, 可以很直接的给assets目录下所有文件都设置过期时间无限长的缓存.
/feed.xml
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
Content-Type: application/rss+xml
/*.html
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
/
Cache-Control: no-cache, no-store, must-revalidate
Pragma: no-cache
Expires: 0
/assets/*
Cache-Control: max-age=31536000, immutable
这里需要注意千万不要顺手把index.html和/给缓存下来了, 不然的话拿到的index.html一般都不会是最新的, 访问的assets内资源也会是从缓存里拿, 这样博客就更新困难了.
如果你是用cf的page功能部署的博客, 那么只需要在public文件夹或者项目根目录新建一个_headers, 再把上面的东西复制进去就可以了.
稍微看了一下使用hexo的同学的博客, 发现hexo不太适合配置缓存, 除非使用了一些构建工具, 或者只缓存某些确实很久不会改变的东西. 默认主题的打包貌似是不带有标识符的. 不过也可以根据自己的更新频率来配置缓存.
强缓存与协商缓存
既然都到这里了, 随便巩固一下HTTP缓存的知识点吧.
首先需要明确的是缓存基本只对再次访问有效, 如果你的路由器或者别的什么代理服务器之前也缓存过, 那首次访问也有效.
当用户首次访问一个网站时, 浏览器请求完资源会根据响应头里缓存相关字段进行缓存. 如果没有相关字段的话, 浏览器不同相关的做法也不同. 谷歌浏览器通常不会进行缓存, 每次都重新请求.
响应头有这些缓存相关字段:
Cache-Control 这里有一个max-age, 使用绝对秒数. 这里的优先级更高
Expires 一个时间戳, 在这之前就没过期
ETag 标识符
Last-Modified
浏览器会把这些字段存起来, 再次访问时就会检查这些字段, 判断缓存是否有效. 如果有效, 那就使用使用缓存, 不跟服务端协商了. 这就是 强缓存 .
如果无效, 那就会向服务端发起一个请求, 并带上这个资源的标识符等字段. 服务端检查这些字段, 判断浏览器的缓存是否有效. 如果有效的话, 那就返回一个304, 告诉浏览器缓存有效. 浏览器知道之后会更新字段, 然后使用缓存; 如果无效的话, 那就返回200, 并且把新的资源发过去, 浏览器知道后更新缓存及相关字段. 这就是 协商缓存 .
WEB缓存器
众所周知, 如果客户端和服务端, 其实还有一个可以介于中间的东西, WEB缓存器. 这个WEB缓存器也可以缓存一些东西, Cache-Control有些字段可以指示缓存器如何缓存.
第一个用户向WEB缓存器请求资源时, 如果缓存器没有, 它就会向服务端请求资源, 然后缓存下来, 转发给用户.
第二个用户来请求同样的资源时, 缓存器就有了相关资源, 如果有效那就直接发给用户了.
像这样的缓存器有很多, 毕竟如果全部人都只向一个服务器请求资源那这个服务器估计就要炸了, 需要多个服务器来作为缓存器, 实现负载均衡.
同时, 服务器的成本可能有点高, 有些厂商可能会使用用户来作为缓存器节省自己的成本.
以B站为例, 假如小A刚看完1号视频, 同地区小B也打算看1号视频, B站可能为了节约成本, 直接让小B跟小A请求资源. 这样自己维护服务器的成本就间接地转移到了用户身上.
这里就会使用到一个P2P的东西, 双方既可以作为服务端, 也可以作为客户端.
这里只是简简单单举一个例子, B站也不一定会这么做. 如果这么做的话也不用担心, 使用浏览器刷B站还是正常的, B站最多魔改一下自己的客户端, 不太可能改所有人的浏览器.
结尾
怎么说呢, 感觉还真是绕了一大段路. sw缓存或许对于博客来说确实没多少意义吧, http缓存配置得更加简单有效.