Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【2021-07-14〜2021-07-15】HTTP缓存机制 #8

Open
superDCH opened this issue Jul 15, 2021 · 0 comments
Open

【2021-07-14〜2021-07-15】HTTP缓存机制 #8

superDCH opened this issue Jul 15, 2021 · 0 comments
Labels

Comments

@superDCH
Copy link
Owner

Web 缓存大致可以分为:数据库缓存、服务器端缓存(代理服务器缓存、CDN 缓存)、浏览器缓存。

浏览器缓存可分为: HTTP 缓存、indexDB、cookie、localstorage 等等。

下面讲讲http缓存的强缓存和协商缓存:

(一)强缓存

定义:直接从本地比对读取,不去请求服务器,返回的状态码是 200。

[关键字段:expires 、 cache-control]

(1)Expires:具体日期(如: Mon,18 Oct 2066 23:59:59)

该字段是http1.0时的规范,它的值为一个绝对时间的GMT格式的时间字符串。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。

(2)cache-control: max-age=xxxx,public

客户端和代理服务器都可以缓存该资源;
客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,如果用户做了刷新操作,就向服务器发起http请求

(3)cache-control: max-age=xxxx,private

只让客户端可以缓存该资源;代理服务器不缓存
客户端在xxx秒内直接读取缓存,statu code:200

(4)cache-control: max-age=xxxx,immutable

客户端在xxx秒的有效期内,如果有请求该资源的需求的话就直接读取缓存,statu code:200 ,即使用户做了刷新操作,也不向服务器发起http请求

(5)cache-control: no-cache

跳过设置强缓存,但是不妨碍设置协商缓存;一般如果你做了强缓存,只有在强缓存失效了才走协商缓存的,设置了no-cache就不会走强缓存了,每次请求都回询问服务端。

(6)cache-control: no-store

不缓存,这个会让客户端、服务器都不缓存,也就没有所谓的强缓存、协商缓存了。

[Cache-Control与Expires可以在服务端配置同时启用,同时启用的时候Cache-Control优先级高。]

(二)协商缓存

会去服务器比对,若没改变才直接读取本地缓存,返回的状态码是 304。

[关键字段: Last-Modify/If-Modify-Since 、 ETag/If-None-Match]

(1)Last-Modify/If-Modify-Since

浏览器第一次请求一个资源的时候,服务器respone的header中会加上Last-Modified,Last-Modified是一个时间,标识该资源的最后修改时间,例如Last-Modified: Thu,31 Dec 2037 23:59:59 GMT。

当浏览器再次请求该资源时,request的请求头中会包含If-Modified-Since,该值为缓存之前返回的Last-Modified的值。服务器收到If-Modified-Since后,根据资源的最后修改时间判断是否命中缓存。

如果命中缓存,则返回304,并且不会返回资源内容,并且不会返回Last-Modified。

(2)ETag/If-None-Match

浏览器第一次请求一个资源的时候,服务器respone的header中会加上Etag,值是一个校验码(可以是哈希值)。ETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据浏览器request发送的If-None-Match值来判断是否命中缓存。

思考:为什么有Last-Modify,还需要ETag?

(1)一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候我们并不希望客户端认为这个文件被修改了,而重新GET;

(2)某些文件修改非常频繁,比如在秒以下的时间内进行修改,(比方说1s内修改了N次),If-Modified-Since能检查到的粒度是s级的,这种修改无法判断(或者说UNIX记录MTIME只能精确到秒);

(3)某些服务器不能精确的得到文件的最后修改时间。

[Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。]

参考:
https://www.jianshu.com/p/fb59c770160c
https://www.jianshu.com/p/9c95db596df5
https://www.cnblogs.com/yxkNotes/p/13931717.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant