http 缓存 不是在http服务上进行缓存,而是将资源缓存放在 浏览器 或 服务端,利用 http 报头的一系列字段通讯,浏览器或者服务端去判断 资源的缓存状态,时间,是否是最新资源等。
header解释
Expires
日期/时间之后,响应被认为是过期的 http1.1的属性
response -> Expires: Wed, 21 Oct 2015 07:28:00 GMT
Age
一般当服务器用自己的缓存实体去响应请求的时候,可以用Age 去表示实体从产生到现在的时间。
response -> Age: 24 单位:秒
Cache-Control
request 控制指令
no-cache
no-cache这并不意味着“不缓存”。no-cache允许缓存存储响应,但要求它们在重用之前重新验证它。如果您想要的“不缓存”的感觉实际上是“不存储”,那么no-store就是要使用的指令。
request -> Cache-Control: no-cache
max-age
Cache-Control: max-age=604800
只接受 Age 值 小于max-age 的内容,即没有过期的请求对象。
max-stale
可以接受过去的对象,但是过期时间必须小于 max-stale
min-fresh
接受生命期大于其当前 Age 跟 min-fresh 值之和的缓存
response 控制指令
pubilc
可以用Cache中内容回应任何用户
private
只能用缓存内容回应先前请求该内容的具体用户
no-cache
可以设置那些内容不用缓存
max-age
设置响应中包含对象的过期时间
Etag
一个资源的(url)标记,服务端返回会返回这个资源的Etag,如果服务端修改了资源,在下次返回资源的时候会重新生成一个新的Etag,客户端在请求的时候会带上这个Etag(放在 If-None-Match 上) 服务端会通过Etag对资源进行对比。
ETag: W/"<etag_value>"
ETag: "<etag_value>"
etag_value 是一个随机串或者时间戳
If-None-Match
如果上次文件的 response-header 中含有Etag,则会用 if-none-match : 上次etag, 放在request中请求到服务器,服务判断后返回200或者304
If-None-Match: "<etag_value>"
If-None-Match: "<etag_value>", "<etag_value>", …
If-None-Match: *
If-Modified-Since
如果上次文件返回中包含 Last-Modified ,则会带上 If-Modified-Since:上次 Last-Modified, 放在request中请求到服务器,服务判断后返回200或者304
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
Last-Modified
服务器设置的文件最后修改时间,比如文件的最后修改时间或者最后创建时间
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT
流程解释
- 浏览器会先判断 Cache-Control 来判断内容是否过期,如果没有过期,则直接读取浏览器缓存,不发送http请求 (这里判断 Expires 也可以,但是 Expires 是再http1.1之前比较通用,1.1之后推荐使用 Cache-Control设置相对时间,而不是通过 Expires 设置的绝对时间,如果都设置了,优先Cache-Control 生效 )
- 浏览器判断请求的url 在上次请求是否有返回的Etag,如果有,则将这个Etag 的值放在请求头的 If-None-Match 中,请求到服务器,让服务器判断资源是否是最新的,如果服务端Etag未被修改,则返回给浏览器304,如果修改则取最新的资源 并返回200
- 然后浏览器判断请求的url 在上次请求是否有返回的 Last-Modified 信息,有则被 If-Modified-Since 带上请求到服务端,服务端判断 从 Last-Modified 的时间开始 是否有新的更新,返回304 或 200
- 如果没有Etag 也没有 Last-Modified 则直接向服务器发送请求。
强缓存和协商缓存
强缓存
Expires + Chahe-Control
浏览器直接通过上次访问该url 留下的 过期时间判断 资源是否过期,不向服务器发请求。
协商缓存
( Etag + If-None-Match )/ (Last-Modified + If-Modified-Since)
通过上次请求响应头中的Etag 或者 Last-Modified 在本次请求头中 通过 If-None-Match 和 If-Modified-Since 发送给服务端,让服务端去判断资源是否有更新,返回给浏览器 304 或者200