1、如何设置浏览器缓存
-
Expires(实体首部字段):服务端返回的到期时间,分为“相对文件的最后访问时间”和“绝对修改时间”。缺点:返回的是服务端时间,比较的是客户端时间,如果不一致可能出现错误
-
Cache-Control(通用首部字段):
- private
- public
- max-age=xxx:缓存内容在xxx秒后失效
- no-cache:需要用另一种缓存策略来验证缓存(ETag,Last-Modified)
- no-store:不进行缓存
-
**Last-Modified(**实体首部字段):
- 浏览器请求获得文件后,服务器返回该文件的最后修改时间Last-Modified
- 下一次请求会带上If-Modified-Since标识,如果If-Modified-Since等于服务器的文件修改时间,则表示文件没有修改,返回304状态码
- 浏览器从浏览器缓存中读取文件。如果If-Modified-Since小于服务端的文件修改时间,则浏览器会重新发送请求获取文件,返回状态码200
-
Etag(响应首部字段):服务器文件的唯一标识
- 服务器返回Etag字段给浏览器,当文件变化时Etag值也会发生变化
- 下次请求会带上If-None-Match即浏览器保留的ETag值,如果发送了变化,则文件被修改,需要重新请求,返回200状态码
- 反之浏览器就从缓存中读取文件,返回304状态码
2、 四者区别
- 当Cache-Control设置为max-age=xx并且同时设置Expires时,Cache-Control的优先级更高
- 当ETag和Last-Modified同时存在时,服务器先会检查ETag,然后再检查Last-Modified,最终决定返回304还是200
3、为何既有last-modified又有Etag
考虑以下情况:
- 一些文件也许会周期性的更改,但是他的内容并不改变(仅仅改变的修改时间),这个时候,我们并不希望客户端认为这个文件被修改了,而重新 get
- 某些文件修改非常频繁,比如在秒以下的时间内进行修改(比方说 1s 内修改了 N 次),If-Modified-Since能检查到的粒度时 s 级的,这种修改无法判断(或者说 UNIX 记录 MTIME只能精确到秒)
- 某些服务器不能精确得到的文件的最后修改时间
所以利用Etag可以更准确的控制缓存。