推荐阅读:
伯乐在线——HTTP 缓存机制一二三
IMWeb前端博客——HTTP缓存控制小结
IT笔录——http消息头
http缓存机制
关键头部字段
- cache-control、 Pragma
- if-Match、if-None-Match
- if-Modified-Since、if-Unmodified-Since
- ETag
- Expires、Last-Modified
Pragma
http1.0可用,现在为了向下兼容,也设置该头部,只有一个值:no-cache禁用缓存
Expires
设置缓存时间(该时间相对于服务器),接受一个GMT(格林尼治时间),用来告诉浏览器过期时间,如果还没有过这个时间则不发送请求。
Expires: Sun Jul 15 2018 19:13:07 GMT
cache-control
也可用来设置缓存时间,http1.1与http1.0可用,三者优先级:
Pragma > Cache-Control > Expires
可设置多个值,比如常用的:no-cache, max-age, public, private
Last-Modified
接受一个格林尼治时间,说明资源的最近一次的修改时间,该字段的作用是当某个资源保存的缓存时间过期了,但服务器并没有更新过这个资源,那么可以告诉客户端此资源没有更新,可以获取缓存中的内容(返回304,不返回实体内容)
if-Modified-Since
Last-Modified的值会在下一次的请求中通过if-Modified-Since传递给服务器,如果它的值和此时服务器的Last-Modified值一致,说明没有修改,服务器返回304。如果不一致则当作正常请求处理,返回资源和200状态码。
ETag
服务端资源有可能被更新了,但是实际内容并没有改变。但是这样依然会引起Last-Modified的更新,服务器给客户端返回没有任何改变的内容。为了解决这个问题,引入了ETag。用于http1.1。
服务器为资源生成一个唯一的字符串,如通过md5编码。只要不变,生成的字符串就不变。在客户端请求资源的时候,将该ETag一起返回给客户端,客户端保留该ETag,下次请求的时候带上。然后比较ETag,相同则表示内容相同,返回304;不同,返回资源和200状态码。
If-None-Match
ETag的值会通过if-None-Match头部传递给服务器,然后服务器比较ETag的值,相同则表示内容相同,返回304;不同,返回资源和200状态码。
另外的 if-None-Match,if-Unmodified-Since
他们不是用来实现缓存策略的,而是用来优化并发控制,他们的作用是,使得当前请求成为条件式请求:只有当资源在指定的时间之后没有进行过修改的情况下,服务器才会返回请求的资源,或是接受 POST 或其他 non-safe 方法的请求。例如在某些场景:假如在原始副本获取之后,服务器上所存储的文档已经被修改,那么对其作出的编辑会被拒绝提交。
总结
- Expires / Cache-Control用来设置缓存时间,即资源有效时间。状态码 200(from cache),可避免请求发送到服务器。
- Last-Modified / ETag用来判断资源是否被修改了。状态码 304(not change),可避免传输相同的资源内容,造成带宽和时间的浪费。
使用原则
- 需要兼容HTTP1.0的时候需要使用Expires,不然可以考虑直接使用Cache-Control
- 需要处理一秒内多次修改的情况,或者其他Last-Modified处理不了的情况,才使用ETag,否则使用Last-- Modified。
- 对于所有可缓存资源,需要指定一个Expires或Cache-Control,同时指定Last-Modified或者Etag。
- 可以通过标识文件版本名、加长缓存时间的方式来减少304响应。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。