浏览器缓存与304状态码

Zoella Lv3

总结

出现304状态码的条件

  • 不禁止缓存
  • 不检查本地缓存是否过期;或者检查本地缓存、且未过期
  • 有Etag,请求头中有If-None-Match;或者有Last-Modified,请求头中有If-Modified-since
  • 缓存有效

图1

一、详细讨论

1、是否禁止缓存

禁止缓存:缓存中不得存储任何关于客户端请求和服务端响应的内容,客户端每次发起的请求都会下载完整的响应内容

在请求头中,Cache-Control: no-storePragma: no-cache 都可以禁止缓存

区别Pragma: no-cache 可用于 http 1.0http 1.1,而 Cache-Control: no-store 只能用于 http 1.1

2、是否检查本地副本是否过期

Cache-Controno-cachemust-revalidate 两个可选值控制

  • no-cache:告诉浏览器、缓存服务器,不管本地副本是否过期,使用资源副本前,必须到源服务器进行副本有效性校验
  • must-revalidate:告诉浏览器、缓存服务器,本地副本过期前,可使用本地副本;本地副本一旦过期,必须去源服务器进行有效性校验

3、检查本地副本是否过期

与「缓存的过期机制」相关的响应头字段(优先级依次降低):

(1)max-age=<seconds>

表示资源能被缓存的最大时间,通常和 must-revalidate 一起使用:

1
2
// 表示 本地副本过期前,可使用本地副本,缓存时间为60秒
Cache-Control: max-age=60, must-revalidate

(2)Expires

表示资源的过期时间。
如果无max-age但有Expires,通过比较ExpiresDate的值来判断是否缓存有效:

图2

(3)Last-Modified

表示资源的最后修改时间。
如果无max-ageexpires但有Last-Modified,缓存的时长等于(Date-Last-Modified)/10

图3

如果都没有,浏览器将不会对该需求进行缓存。

4、本地副本没过期

直接从缓存中读取资源,并返回200状态码。

图4

5、本地副本已过期

进行「源服务器进行有效性校验」的前期准备。

(1)If-None-Match

首先,在请求头里寻找If-None-Match字段(其值为服务器上次返回的ETag响应头的值)

图5
图6

(2)If-Modified-Since

如果没有If-None-Match,则在请求头中寻找If-Modified-Since字段(其值为服务器上次返回的Last-Modified响应头中的日期值)

图7
图8

(3)都没有

如果If-None-MatchIf-Modified-Since都没有,则直接向服务器请求数据

6、去源服务器进行有效性校验

如果请求头中有If-None-MatchIf-Modified-Since,则到源服务器进行有效性校验。
如果源服务器资源没有变化,则会返回304;如果有变化,则返回200。

7、上述流程的总结图

图9

二、补充

私有缓存和公共缓存

Cache-Control还有两个值:privatepublic

  • public 表示该响应可被任何中间人(比如中间代理、CDN等)缓存。
  • private 表示该响应是专用于某单个用户的,不能被中间人缓存,应用于浏览器的私有缓存中(比如:带有HTTP验证信息(帐号密码)的页面 或 某些特定影响状态码的页面*)。

“某些特定影响状态码的页面”指具有特殊语义的状态码,比如:

(1)401 Unauthorized

当访问受保护的资源时,如果用户未通过身份验证,服务器可能返回401状态码。此时通常只应允许客户端(即用户的浏览器)缓存该响应,因为该内容对于其他用户是不适用的。
403 Forbidden:

这个状态码表示服务器理解请求但拒绝执行它。在某些情况下,即使是公共内容,也可能出于安全考虑而不被中间缓存,因此可以标记为 private。

(2)404 Not Found

如果某个资源不存在,虽然它是公开的,但可能在某些应用场景下不希望被中间缓存。这通常取决于具体的业务逻辑和需求。

(3)500 Internal Server Error

这种错误通常表示服务器出现了问题,返回的内容可能不稳定,因此不应被中间缓存。类似地,可以通过设置 Cache-Control: private 来确保只有用户的浏览器缓存。

private 使用场景

(1)用户特定数据

如个性化推荐、用户历史记录等,仅对特定用户合适,其他用户无法访问,即便返回成功状态(200 OK),为了保护用户隐私,建议使用 private。

(2)临时性数据

如操作结果、表单提交后给予反馈的信息等,这类信息通常只需当前用户知道,对其他用户无意义,适合标记为 private。

  • Title: 浏览器缓存与304状态码
  • Author: Zoella
  • Created at : 2024-10-16 17:52:10
  • Updated at : 2024-10-16 20:42:12
  • Link: https://zoella-w.github.io/2024/10/16/24-浏览器缓存与304状态码/
  • License: This work is licensed under CC BY-NC-SA 4.0.