条件请求用途(缓存更新和断点续传)及例子

条件请求有两个用途

  • Cache update
  • Integrity of a partial download

一、Cache update

条件请求用途(缓存更新和断点续传)及例子_第1张图片

条件请求是指浏览器能够询问服务器,是否有最新资源的副本。浏览器会发送些它持有的缓存资源的一些信息,服务器决定是否返回更新的数据或者使用浏览器的副本(也就是资源没更新)。若依然使用浏览器的副本,则响应状态码为304(not modified)。

虽然条件请求也会在网络中发生调用,但是在资源未修改时,其响应体是空的(节省了传输资源给客户端的成本)。服务器能够很快的在不访问资源的情况下决定资源最后修改时间。

 

1.Time-based

若资源在浏览器副本缓存后改变,则会传送内容;否则返回304。

1.1实现过程

为了保证条件请求,应用通过Last-Modified指定资源的最近修改时间,返回给浏览器。

Last-Modified: Mon, 03 Jan 2011 17:45:57 GMT

下次,浏览器请求这个资源时,会询问资源是否自从这个时间修改过,通过If-Modified-Since。

If-Modified-Since: Mon, 03 Jan 2011 17:45:57 GMT

若自从Mon, 03 Jan 2011 17:45:57 GMT时间没有修改过,则返回响应码是304,响应体是空的响应。

1.2图示

条件请求用途(缓存更新和断点续传)及例子_第2张图片

 

2.Content-based

ETag(or Entity Tag)是资源版本的标识符。

工作方式类似于Last-Modified,只是ETag值是资源的digest(比如,MD5 hash)。

当Last-Modified时间很难确定时,ETag就很有用了。

2.1实现

//服务器响应头
ETag: "15f0fff99ed5aae4edffdd6496d7131f"

后续,若浏览器带If-None-Match,把上一次请求的资源版本ETag发送给服务器

//客户端请求头
If-None-Match: "15f0fff99ed5aae4edffdd6496d7131f"

与If-Modified-Since类似,若版本一致,则说明服务器版本未修改过,可以使用缓冲,返回状态码304 

2.2图示

条件请求用途(缓存更新和断点续传)及例子_第3张图片

 

二、Integrity of a partial download

若要支持断点续传请求,则要在响应头部Access-Ranges:bytes。否则写If-Range无用

If-Range的值是ETag或Last-Modified的值。若一致,则作为范围请求处理,否则返回全部资源

If-Range要和Range共同使用,否则服务器会忽略。

(这样做也是合理的,因为ETag不变,说明资源未变,则直接返回客户端请求的资源即可;若资源改变,请求的部分资源没有了,应该返回所有的新资源)

The If-Range HTTP request header makes a range request conditional: if the condition is fulfilled, the range request will be issued and the server sends back a 206 Partial Content answer with the appropriate body. If the condition is not fulfilled, the full resource is sent back, with a 200 OK status.

Range指定范围,若是合法且If-Range有效,则返回206;若范围不合法,则返回416 Range Not Satifiable error。服务器也可忽略Range返回200整个文件(范围错误或者Etag改变)。

工作流程:

Etag 由服务器端生成,客户端通过 If-Range 条件判断请求来验证资源是否修改。请求一个文件的流程如下:

第一次请求:

  1. 客户端发起 HTTP GET 请求一个文件。
  2. 服务器处理请求,返回文件内容以及相应的 Header,其中包括 Etag(例如:627-4d648041f6b80)(假设服务器支持 Etag 生成并已开启了 Etag)状态码为 200。

第二次请求(断点续传):

  1. 客户端发起 HTTP GET 请求一个文件,同时发送 If-Range(该头的内容就是第一次请求时服务器返回的 Etag:6274d648041f6b80)。
  2. 服务器判断接收到的 Etag 和计算出来的 Etag 是否匹配,如果匹配,那么响应的状态码为 206;否则,状态码为 200。

条件请求用途(缓存更新和断点续传)及例子_第4张图片

若不用If-Range,则需要发两次请求。因为若资源改变,会返回客户端412;客户端再发起请求,获得新资源

 

参考:

https://devcenter.heroku.com/articles/increasing-application-performance-with-http-cache-headers

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Conditional_requests

你可能感兴趣的:(HTTP协议)