• 概括如下图:

    缓存验证

    协商缓存就是缓存验证。

    触发时机:

    触发条件:

    只有在服务器返回强校验器或者弱校验器时才会进行验证。

    附带条件请求

    形如 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 和更新后的资源。HTTP缓存——协商缓存(缓存验证)-LMLPHP

    HTTP缓存——协商缓存(缓存验证)-LMLPHPHTTP缓存——协商缓存(缓存验证)-LMLPHP

    08-21 17:09