前端实践-HTTP缓存| 豆包MarsCode AI刷题

61 阅读5分钟

HTTP缓存

在HTTP协议中,缓存策略是一个重要的特性,它允许浏览器在本地存储资源的副本,以便在下次请求时可以更快地加载。缓存策略主要包括强缓存和协商缓存两种。

强缓存

强缓存是指当浏览器请求资源时,如果本地缓存中有该资源的副本,并且该副本没有过期,那么浏览器就会直接使用本地缓存,而不会向服务器发送请求。强缓存的过期时间是由服务器在响应头中设置的,常用的字段有ExpiresCache-Control

通过 Expires 和 Cache-Control 两个响应头字段来控制,如果同时存在,则后者优先级高于前者。

服务器通知浏览器一个缓存时间,在缓存时间内,下次请求直接从本地缓存中读取资源而不发起请求。不在时间内,执行比较缓存策略。

① 强缓存命中则直接读取浏览器本地的资源,在network中显示的是from memory或者from disk

② 控制强制缓存的字段有:Cache-Control(http1.1)和 Expires(http1.0)

③ Cache-control是一个相对时间,用以表达自上次请求正确的资源之后的多少秒的时间段内缓存有效

③ Expires是一个绝对时间。用以表达在这个时间点之前发起请求可以直接从浏览器中读取数据,而无需发起请求

④ Cache-Control 的优先级比 Expires 的优先级高。前者的出现是为了解决 Expires 在浏览器时间被手动更改导致缓存判断错误的问题。如果同时存在则使用 Cache-control

协商缓存

协商缓存是指当浏览器请求资源时,如果本地缓存中有该资源的副本,但是该副本已经过期,那么浏览器就会向服务器发送请求,询问服务器该资源是否有更新。如果服务器返回304 Not Modified,表示资源没有更新,浏览器就会使用本地缓存;如果服务器返回200 OK,表示资源有更新,浏览器就会使用服务器返回的最新资源。协商缓存的判断依据是服务器在响应头中设置的Last-ModifiedETag字段。

如果强制缓存未命中,但协商缓存可用,则会向服务器发送条件请求,请求头中设置了If-Modified-Since 或者 If-None-Match的值, 服务端根据这两个值,去验证是否命中协商缓存。如果命中了协商缓存,会返回 304 状态,直接使用浏览器缓存。

通过 Last-Modified 和 Etag 两个响应头字段来控制,如果同时存在,则后者优先级高于前者

① 协商缓存的状态码由服务器决策返回 200或者304

② 对比缓存在请求数上和没有缓存是一致的,但如果是 304 的话,返回的仅仅是一个状态码而已,并没有实际的文件内容,因此在响应体体积上的节省是它的优化点。

③ 协商缓存有 2 组字段(不是两个),控制协商缓存的字段有:Last-Modified / If-Modified-since(http1.0)和 Etag / If-None-match(http1.1)

Last-Modified / If-Modified-since表示的是服务器的资源最后一次修改的时间; Etag / If-None-match表示的是服务器资源的唯一标识,只要资源变化,Etag就会重新生成; ④ Etag / If-None-match 的优先级比 Last-Modified / If-Modified-since高

缓存过程

HTTP缓存都是从第二次请求开始的:

第一次请求资源时:

服务器返回资源,并在response header(响应头)中回传资源的缓存策略;

第二次请求时:

浏览器判断这些请求参数,击中强缓存就直接200;

否则就把请求参数加到request header头中传给服务器,看是否击中协商缓存,击中则返回304,否则服务器会返回新的资源。

下面以Chrome浏览器为例,分析其涉及的请求中的缓存策略。

首先,打开Chrome浏览器,访问一个网站,比如https://www.example.com。然后,按下F12键打开开发者工具,切换到网络选项卡。

image.png

在网络选项卡中,可以看到所有的请求和响应。找到一个请求,比如www.example.com可以看到该请求的详细信息,包括请求头和响应头。

image.png

在响应头中,可以看到Cache-Control字段,该字段表示资源缓存的最大有效时间,在该时间内,客户端不需要向服务器发送请求。该字段的值为max-age=604800,表示该资源的缓存时间为604800秒,即168小时。这是一个强缓存的设置,表示在168小时内,浏览器再次请求该资源时,会直接使用本地缓存,而不会向服务器发送请求。

image.png

如果Cache-Control字段的值为no-cacheno-store,则表示不允许缓存,浏览器每次请求都会向服务器发送请求。比如content.css,

image.png

如果Cache-Control字段的值为must-revalidate,则表示在缓存过期后,必须向服务器验证资源是否更新,然后才能使用本地缓存。

Expires字段,该字段是服务器响应消息头字段,告诉浏览器在过期时间之前可以直接从浏览器缓存中存取数据,告诉浏览器在未过期之前不需要再次请求,直接从缓存中存取数据。

Last-Modified字段,资源最后修改时间。在协商缓存中,如果响应头中有Last-Modified字段,那么浏览器在下次请求时,会在请求头中添加If-Modified-Since字段,该字段的值就是Last-Modified字段的值。如果服务器发现资源没有更新,就会返回304 Not Modified。

ETag字段,文件内容唯一标识 。如果响应头中有ETag字段,那么浏览器在下次请求时,会在请求头中添加If-None-Match字段,该字段的值就是ETag字段的值。如果服务器发现资源没有更新,就会返回304 Not Modified。