一. If-Modified-Since与Last-Modified
- 首次请求与响应
1)浏览器首次访问时,请求的Header中没有If-Modified-Since。
2)响应状态码为200,响应的Header中返回了Last-Modified并完整地返回了文件内容。 - 本地有缓存,文档在服务器未修改
1)浏览器再次访问,请求的Header携带了If-Modified-Since,其值为上次响应的Last-Modified的时间。
2)此文件没有修改过,服务器返回响应状态码为304,响应的Body为空。 - 本地有缓存,文档在服务器有修改
1)在服务器修改文件。
2)浏览器的请求的Header携带If-Modified-Since。
3)由于文件已修改并且比If-Modified-Since的时间新,因此响应状态码为200,返回文件内容并在响应的Header中返回了Last-Modified,其值为文件的最新修改时间。
二. ETag与If-None-Match(If-Match)
按照HTTP标准,Last-Modified只能精确到秒级。ETag的出现可以很好的解决这个问题,资源实体的标记(entity tag),强标识一个资源。
*在秒级以内多次修改,Last-Modified和Expires无法表示出来,因为Last-Modified和Expires最小粒度为秒级。
*对资源多次修改,但是最后又修改回最初的内容,实际上内容并没有改变。
*ETag值是根据实际内容变更才更新,所以可以更准确的标志资源。
- 服务器端创建资源,生成ETAG,每次修改也更新ETAG。
- 客户端首次访问资源,服务器返回资源实体内容和在头区中返回ETAG值,客户端保存实体内容和ETAG值。
- 客户端再次访问资源的时候,在头域(header)中加入“If-match:etag值”指令。
- 服务器接受到请求后,检查资源的ETAG值是否与请求的If-match指定的etag值相同(强匹配),如果匹配则响应304 Not Modified,表示资源未改变,客户端可以直接使用前面请求中保存的资源,如果不匹配才返回资源实体(entity,也就是body体).或者:客户端再次访问资源的时候,在header中加入“If-None-Match:etag值”,如果服务器的ETAG值匹配客户端请求的etag值则返回412,表示条件冲突,不匹配则返回实体内容。
- 客户端继续使用缓存的资源。
If-Match:匹配则返回实体内容,否则响应307,不返回实体内容。
If-None-Match:不匹配则返回实体内容,否则响应412错误。
参考:
http://aofengblog.blog.163.com/blog/static/631702120152322848786/
http://acooly.iteye.com/blog/1317272