浏览器缓存(Brower Caching)是浏览器在本地磁盘对用户最近请求过的文档进行存储,当访问者再次访问同一页面时,浏览器就可以直接从本地磁盘加载文档。
浏览器缓存的优点有:
- 减少了冗余的数据传输,节省了网费
- 减少了服务器的负担,大大提升了网站的性能
- 加快了客户端加载网页的速度
浏览器缓存主要有两类:协商缓存和强缓存
浏览器在第一次请求发生后,再次请求时:
浏览器会先获取该资源缓存的 header 信息,根据其中的 expires 和 cache-control 判断是否命中强缓存,若命中则直接从缓存中获取资源,包括缓存的 header 信息,本次请求不会与服务器进行通信;
如果没有命中强缓存,浏览器会发送请求到服务器,该请求会携带第一次请求返回的有关缓存的 header 字段信息(Last-Modified/IF-Modified-Since、Etag/IF-None-Match),由服务器根据请求中的相关 header 信息来对比结果是否命中协商缓存,若命中,则服务器返回新的响应 header 信息更新缓存中的对应 header 信息,但是并不返回资源内容,它会告知浏览器可以直接从缓存获取;否则返回最新的资源内容
强缓存
Expires
Expires 是 http1.0 提出的一个表示资源过期时间的 header,它描述的是一个绝对时间,由服务器返回。
Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效。
1 | Expires: Wed, 11 May 2018 07:20:00 GMT |
Cache-Control
Cache-Control 出现于 HTTP / 1.1,优先级高于 Expires ,表示的是相对时间。
1 | Cache-Control: max-age=315360000 |
Cache-Control 的常见其他配置字段:
no-cache
:使用缓存协商,根据服务的协商返回情况看是否使用本地缓存。no-store
:直接禁止游览器缓存数据,每次用户请求该资源,都会向服务器发送一个请求,每次都会下载完整的资源。public
:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。private
:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。
协商缓存
当浏览器对某个资源的请求没有命中强缓存,就会发一个请求到服务器,验证协商缓存是否命中,如果协商缓存命中,请求响应返回的 http 状态为 304 并且会显示一个 Not Modified 的字符串。
协商缓存是利用的是【Last-Modified,If-Modified-Since】
和【ETag、If-None-Match】
这两对 Header 来管理的。
Last-Modify/If-Modify-Since
Last-Modified
表示本地文件最后修改日期,浏览器会在 request header 加上If-Modified-Since
(上次返回的Last-Modified
的值),询问服务器在该日期后资源是否有更新,有更新的话就会将新的资源发送回来。
1 | Last-Modify: Thu,31 Dec 2037 23:59:59 GMT |
但是如果在本地打开缓存文件,就会造成Last-Modified
被修改,所以在 HTTP / 1.1 出现了ETag
。
ETag/If-None-Match
Etag
就像一个指纹,资源变化都会导致 ETag 变化,跟最后修改时间没有关系,ETag
可以保证每一个资源是唯一的。
If-None-Match
的 header 会将上次返回的Etag
发送给服务器,询问该资源的Etag
是否有更新,有变动就会发送新的资源回来。
具体为什么要用ETag
,主要出于下面几种情况考虑:
你可能会觉得使用 Last-Modified 已经足以让浏览器知道本地的缓存副本是否足够新,为什么还需要 Etag 呢?HTTP1.1 中 Etag 的出现主要是为了解决几个 Last-Modified 比较难解决的问题:
一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新 GET;
某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说 1s 内修改了 N 次),If-Modified-Since 能检查到的粒度是 s 级的,这种修改无法判断(或者说 UNIX 记录 MTIME 只能精确到秒);
某些服务器不能精确的得到文件的最后修改时间。
Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。
整体流程图
几种状态码的区别
200
:强缓 Expires/Cache-Control 存失效时,返回新的资源文件200(from disk/memory cache)
:强缓 Expires/Cache-Control 两者都存在,未过期,Cache-Control 优先 Expires 时,浏览器从本地获取资源成功304(Not Modified)
:协商缓存 Last-modified/Etag 没有过期时,服务端返回状态码 304
缓存存储位置:
内存缓存(memory cache)和硬盘缓存(disk cache)
区别 | 内存缓存 | 硬盘缓存 |
---|---|---|
存储内容 | JS,字体,图片等 | CSS 等 |
读取速度 | 快 | 慢 |
时效性 | 进程关闭则清空 | 可以缓存较长时间 |
空间 | 空间小 | 空间大 |