概括如下图:
缓存验证
协商缓存就是缓存验证。
触发时机:
触发条件:
只有在服务器返回强校验器或者弱校验器时才会进行验证。
附带条件请求
形如 If-xxx 这种样式的请求首部字段,都可称为条件请求。
服务器接 收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
协商缓存中,就有很多这样的附带条件请求。
《图解HTTP》
协商缓存 特点:
304(Not Modified)
该状态码虽然是3XX的类别,但是跟301、302不一样,不是重定向的含义。
304,Not Modified。表示服务端资源未改变,可直接使用客户端缓存过的、未过期的资源。
他的触发条件是:
1、客户端采用GET方法,且在请求报文中含有“If-Match”、“If-Modified-Since”、“If-None-Match”、“If-Range”、“If-Unmodified-Since”等字段
2、服务器端接收到请求,允许请求并访问资源。但因客户端的请求未满足条件,就直接返回了304。
304状态码返回时,不包含任何响应的主体部分。
也就是说,如果命中协商缓存,服务端响应请求时,只会返回一个304状态码、并没有实际上的文件内容,因此在响应体体积上的节省是协商缓存的优化点
HTTP/1.0 Last-Modified组
Last-Modified (资源的最后修改日期时间)
实体首部字段:Last-Modified,表示资源最后被修改的时间。
格式如:
last-modified: Thu, 01 Jan 1970 00:00:00 GMT
这句话就像是服务器告诉客户端,你请求的这个文件是1970年1月1日修改的。
Last-Modified是一种缓存弱校验器。说它弱是因为它只能精确到一秒。
如果响应头里含有这个信息,客户端可以在后续的请求中带上 If-Modified-Since 来验证缓存:
If-Modified-Since (比较资源的更新时间)
请求首部字段
他是与Last-Modified对应的字段,存储的是上次缓存的资源最终更新时间,也就是上次缓存资源时获取的Last-Modified的值。
用于确认代理服务器/客户端拥有的本地资源的有效性。
如果在If-Modified-Since字段指定的日期时间后,资源发生了改变,服务器会接受请求。
上图中,服务端拿着他的值和服务端本地被请求资源的Last-Modified进行比较:
他的格式如:
if-modified-since: Thu, 01 Jan 1970 00:00:00 GMT
HTTP/1.1 Etag组
Etag (资源的匹配信息)
响应首部字段,缓存的一种强校验器。
实体标记(Etag)是与特定资源关联的特定值,是资源唯一性标识的字符串。服务器会为每份资源分配对应的 ETag 值。 并通过响应头首部字段告知客户端资源的实体标识。
格式如:
etag: f7b80870fbcd8f9da18ab22d2ef1932c
特点:
强弱Etag:
ETag 中有强 ETag 值和弱 ETag 值之分。
强ETag值
强 ETag 值,不论实体发生多么细微的变化都会改变其值。
ETag: "usagi-1234"
弱ETag值
弱 ETag 值只用于提示资源是否相同。只有资源发生了根本改变,产 生差异时才会改变 ETag 值。
这时,会在字段值最开始处附加 “W/”。如下:
ETag: W/"usagi-1234"
If-None-Match (比较实体标记)
请求首部字段
他是与Etag对应的字段,存储的是上次缓存的资源的实体标记值,也就是上次缓存资源时获取的Etag的值。
协商缓存时,客户端携带该字段与服务端资源的Etag字段值进行比对,只有在If-None-Match的字段值与Etag值匹配不上、不一致时,命中协商缓存。
在GET或HEAD请求方法中,使用If-None-Match可获取最新的资源。
格式如:
if-none-match: f7b80870fbcd8f9da18ab22d2ef1932c
他和If-Match的作用相反。
If-Match 与412 状态码
用法和规则基本同If-None-Match,但判断逻辑完全相反。
If-Match的这个条件的判断逻辑是:只有当 If-Match 的字段值跟 ETag 值匹配一致时才会命中协商缓存。服务器才会接受请求 并返回200和新数据。
反之,服务器返回状态码 412 Precondition Failed 的响应。
还可以使用 星号(*) 指定 If-Match 的字段值。
针对这种情况,服务器将会忽略 ETag 的值,只要资源存在就处理请求。
if-match: f7b80870fbcd8f9da18ab22d2ef1932c
或者
if-match: *
对比
首先,Etag的优先级高于Last-Modified。
Last-Modified和Etag的优缺点分析如下:
Last-Modified优点
不存在版本问题,每次请求都会去服务器进行校验。服务器对比最后修改的时间,如果相同返回 304,不同的话返回 200 以及相应的数据资源
Last-Modified缺点
Etag优点
Etag缺点
两组字段流程整理如下
最后再整体回顾、复习一下子。
(注意:实际HTTP1.1的请求中,两组字段同时包含在请求及响应头中,我这里为了加深组CP的印象,分开阐述)
1、Last-Modified组整体流程如下:
2、Etag组整体流程如下:
浏览器在发起请求时,服务器在响应头中返回请求资源的唯一标识。在下一次请求时,会将上一次返回的 Etag 值赋值给 If-None-match 并添加在响应头中。服务器将浏览器传来的 if-no-matched 跟自己的本地的资源的 Etag 做对比,如果匹配,则返回 304 通知浏览器读取本地缓存,否则返回 200 和更新后的资源。