Http Cache:缓存的使用和注意事项
HTTP缓存一般通过三个响应头实现:Cache-Control、ETag、Last-Modified 三个头实现。
其中Cache-Control的内容有:
- no-cache:这个指令意味着缓存的内容必须在使用前通过服务器进行验证。注意,尽管名字叫 “no-cache”,但它并不意味着不可以缓存,只是要求在使用缓存之前需要向服务器验证。
- no-store:这个指令表示请求或响应的内容不应该被缓存。这通常用于处理敏感信息,不推荐使用(浪费了缓存能力)。
- public:这个指令表示响应可以被任何对象(包括:发送消息的客户端,代理服务器等)缓存,即使响应是对特定用户的认证响应。 【这里public表示可以被中间代理服务器缓存】
- private:这个指令表示响应只能被单个用户(特定的浏览器或者用户代理)缓存,不能被共享缓存(例如 CDN 或代理服务器)缓存。【只限定当前用户缓存】
- max-age=[seconds]:这个指令定义了一个时间长度,表示资源在被视为过时之前可以被缓存和重新使用的最大时间。时间以秒为单位。
- s-maxage=[seconds]:与 max-age 类似,但此指令仅适用于共享缓存(例如 CDN 或代理服务器),并且会覆盖 max-age 和 expires 头。
ETag必须和If-None-Match成对使用。传递 Etag值时,必须使用双引号,不能不包、也不能使用单引号。 如未开启可以在nginx中配置”etag on“启用。
Last-Modified也必须和If-Modified-Since成对使用。其中日期必须和原响应一致。否则不能返回304。 另外也可以使用Expires头,但其中存放的是绝对时间,如果客户端、服务端时间差异大,可能会有问题。
浏览器重新加载功能通过设置max-age=0来实现。参考(https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching#重新加载)
缓存也可以分为强缓存和协商缓存。
- 强缓存:如果资源的缓存设置中指定了适当的缓存头,例如 Cache-Control 中的 max-age 或 Expires 头,且缓存副本仍然在有效期内,浏览器将直接从缓存中提供响应,而不发送实际的请求到服务器。这样可以显著提高性能,因为不需要网络传输和服务器处理。
- 协商缓存:当资源的缓存设置中指定了适当的缓存头,例如 Cache-Control 中的 no-cache 或 must-revalidate 头,或者存在 ETag 和 Last-Modified 头时,浏览器会发送一个条件请求到服务器,询问服务器资源的新鲜度。如果服务器返回 304 Not Modified 响应,表示资源没有更改,浏览器将从缓存中提供响应,而不是实际的资源。
最佳实践建议之一:针对静态文件主页面,可以设置cache-control为no-cache(每次页面都需要验证),然后对主页面中嵌入的静态资源设置较长的max-age,尽可能使用强缓存,避免反复请求网络。