当前位置: 首页 > 工具软件 > last-blog > 使用案例 >

浏览器缓存:expires Cache-Control Last-Modified Etag

莘绍元
2023-12-01

缓存机制

  1. (http1.0中)检查expires过期时间,
    (http1.1中)检查Cache-Control的max-age,优先级更高
    Pragma(兼容http1.0, 在HTTP/1.1协议中,它的含义和Cache- Control相同)
    是否可以直接使用缓存资源?
    可以使用:则返回200(from cache),此时浏览器和服务器没有任何交互
  2. 已过期:
    (1)使用Last-Modified
    If-Modified-Since:最后修改时间
    服务端判断资源有无修改:
    有修改则响应整片资源内容(写在响应消息包体内),HTTP 200
    无修改则响应HTTP 304 (无需包体,节省浏览),告知浏览器继续使用所保存的cache。
    (2) 使用Etag
    If-None-Match:当前资源在服务器的唯一标识
    服务端判断资源有无修改:
    有修改,响应200
    无修改,响应304

注:Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,通过再验证Last-Modified

Cache-control指明当前资源的有效期

  1. Public指示响应可被任何缓存区缓存。
  2. Private指示对于单个用户的整个或部分响应消息,不能被共享缓存处理。这允许服务器仅仅描述当用户的部分响应消息,此响应消息对于其他用户的请求无效。
  3. no-cache:no-cache是会被缓存的,只不过每次在向客户端(浏览器)提供响应数据时,缓存都要向服务器评估缓存响应的有效性。
  4. no-store用于防止重要的信息被无意的发布。在请求消息中发送将使得请求和响应消息都不使用缓存。
  5. max-age指示客户机可以接收生存期不大于指定时间(以为单位)的响应。
  6. min-fresh指示客户机可以接收响应时间小于当前时间加上指定时间的响应。
  7. max-stale指示客户机可以接收超出超时期间的响应消息。如果指定max-stale消息的值,那么客户机可以接收超出超时期指定值之内的响应消息。

Pragma: no-cache

和Cache-Control: no-cache相同
Pragma: no-cache兼容http 1.0 ,Cache-Control: no-cache是http 1.1提供的。
因此,Pragma: no-cache可以应用到http 1.0 和http 1.1,而Cache-Control: no-cache只能应用于http 1.1.

Expires和Cache-Control

Expires要求客户端和服务端的时钟严格同步
HTTP1.1引入Cache-Control来克服Expires头的限制。如果max-age和Expires同时出现,则max-age有更高的优先级。

    Cache-Control: no-cache, private, max-age=0

    ETag: abcde

    Expires: Thu, 15 Apr 2014 20:00:00 GMT

    Pragma: private

    Last-Modified: $now // RFC1123 format

ETag

Etag由服务器端生成,客户端通过If-Match或者说If-None-Match这个条件判断请求来验证资源是否修改。常见的是使用If-None-Match。请求一个文件的流程可能如下:

====第一次请求===

1.客户端发起 HTTP GET 请求一个文件;

2.服务器处理请求,返回文件内容和一堆Header,当然包括Etag(例如”2e681a-6-5d044840”)(假设服务器支持Etag生成和已经开启了Etag).状态码200

====第二次请求===

客户端发起 HTTP GET 请求一个文件,注意这个时候客户端同时发送一个If-None-Match头,这个头的内容就是第一次请求时服务器返回的Etag:2e681a-6-5d0448402.服务器判断发送过来的Etag和计算出来的Etag匹配,因此If-None-Match为False,不返回200,返回304,客户端继续使用本地缓存;流程很简单,问题是,如果服务器又设置了Cache-Control:max-age和Expires呢,怎么办

答案是同时使用,也就是说在完全匹配If-Modified-Since和If-None-Match即检查完修改时间和Etag之后,

服务器才能返回304.(不要陷入到底使用谁的问题怪圈)

为什么使用Etag请求头?

Etag 主要为了解决 Last-Modified 无法解决的一些问题。

  1. Last-Modified标注的最后修改只能精确到秒级,如果某些文件在1秒钟以内,被修改多次的话,它将不能准确标注文件的修改时间

  2. 如果某些文件会被定期生成,当有时内容并没有任何变化,但Last-Modified却改变了,导致文件没法使用缓存

  3. 有可能存在服务器没有准确获取文件修改时间,或者与代理服务器时间不一致等情形

  4. Etag是服务器自动生成或者由开发者生成的对应资源在服务器端的唯一标识符,能够更加准确的控制缓存。Last-Modified与ETag是可以一起使用的,服务器会优先验证ETag,一致的情况下,才会继续比对Last-Modified,最后才决定是否返回304。

IE缓存问题

在IE浏览器下,如果请求的方法是GET,并且请求的URL不变,那么这个请求的结果就会被缓存。解决这个问题的办法可以通过实时改变请求的URL,只要URL改变,就不会被缓存,可以通过在URL末尾添加上随机的时间戳参数(‘t’= + new Date().getTime())

或者:

open(‘GET’,’demo.php?rand=’+Math.random(),true);//

参考:
http://blog.csdn.net/eroswang/article/details/8302191
https://developers.google.cn/web/fundamentals/performance/optimizing-content-efficiency/http-caching?hl=zh-cn
http://uule.iteye.com/blog/2212906

 类似资料: