We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HTTP 协议的缓存机制涉及到多个请求头字段,而且整个缓存机制的细节行为也存在各种情况的差异,譬如说什么时候访问本地缓存不发送请求,什么时候发送请求查看资源是否更新,获取 response 什么情况下更新缓存等。以前我对此一知半解只是笼统的知道一些概念,譬如 Cache-Control 可以控制缓存的时间和是否需要缓存,但是缓存过期后的行为,有缓存后浏览器是否有 http 请求都不甚了解。所以特地 google 下,此篇是对此的知识梳理。
什么情况下可以使用本地缓存?譬如说我们用 get 方式请求了一个资源 http://mytest.domain.com/static/images/bg.png,那么我们下次再请求这个图片资源的时候符合哪些条件可以使用本地缓存呢?
http://mytest.domain.com/static/images/bg.png
http://mytest.domain.com/static/images/bg.png?t=12312321
注1:上述任何提一个条件都可以被 cache-control extension 覆盖 注2:response header中不仅仅可以 Cache-Control: no-cache,还可以 Cache-Control: no-cache="Set-Cookie" 详见
浏览器是通过比较缓存剩余有效时间和当前缓存已存在时间来判断的:response_is_fresh = (freshness_lifetime > current_age)。freshness_lifetime 取值优先级次序如下列表所示(排在上面的优先级越高):
response_is_fresh = (freshness_lifetime > current_age)
freshness_lifetime
注1;如果有多个重复的上述头,那么是非法的,视作 response(资源)过期
规范并没有给出具体的算法,但是给出了最坏情况(but does impose worst-case constraints on their results),如果 response(资源)有 Last-Modified 头,那么推荐用从当前到lastmodified这个时间段的 10% 作为 freshness_lifetime,并且 response(资源)的 current_age 如果已经超过24小时,必须在这个 response 上加上113 warn-code头。很少有浏览器实现了freshness_lifetime的自助计算(推测),所以还是还是鼓励给出上述显式的1 - 3三种情况。
泛泛来说就是 response(资源)在本地的驻足时间加上网络传输时间,因为网络传输时间的计算有多个条件,规范实在看的我头晕,所以具体计算规则详见规范
首先,如果第一次的 response(资源)头中显示申明了一些禁止缓存的头(譬如:"no-store" or "no-cache" 等等),就不存在过期不过期的问题,因为这个资源不允许缓存。其次,过期缓存也不一定不可用,如果在断网或者第二次请求带上 max-stale 这个请求头,那么浏览器可以使用过期的缓存(masx-stale 表示在缓存过期后多少时间内浏览器依然可以使用缓存)。碰到过期缓存,浏览器可以发送一个条件请求(conditional request)。这个请求的 url 依然是第一次请求的 url,只是会带上些当前资源的一些信息,以供服务器验证这个缓存是否依然可用还是需要更新:
服务器会根据不同的条件请求头来验证资源,具体的行为详见规范,这里不细致展开。针对条件请求,服务器返回会有三种情况:
如果是一个304的返回,规范说这个返回可以更新本地缓存,更新策略分三种:
假设第一次请求一个资源,返回 header 里面带上如下字段: Cache-Control: max-age=600 Last-Modified: Wed, 28 Aug 2013 10:36:42 GMT ETag: "124752e0d85461a16e76fbdef2e84fb9"
抛开细枝末节的东西,那么第二次请求通常大致流程图如下:
当前资源缓存是否过期:response_is_fresh = (freshness_lifetime > current_age) | ----------------------------------- | | 是 否 | | 发送请求,带上请求头 从本地缓存中获取资源(不发请求) If-Modified-Since: 此资源Last-Modified的值 If-None-Match: 此资源ETag的值 | 服务器根据 If-Modified-Since 和 If-None-Match 两个值判断资源是否更新过 | ------------------------- | | 是 否 | | 返回一个 status code:200 的 response 返回一个 status code:304 的 response response body 里面是请求的资源 response body 为空 | | 浏览器用 response body里面的资源 依然从本地缓存里面获取资源 替换本地缓存中的资源
当你去浏览器验证的时候可能会碰到一些特殊情况,就是缓存有效,但是你刷新浏览器依然发送的条件请求。其实是因为浏览器在请求头中加入了一些料,譬如: Cache-Control: max-age=0。你刷新的方式可以有很多种,譬如:按F5,按ctrl+F5,在地址栏按回车等等。这些不同的行为都会影响浏览器发送请求的行为。这里有一些参考《在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别》
rfc7234
The text was updated successfully, but these errors were encountered:
No branches or pull requests
HTTP 协议的缓存机制概述
HTTP 协议的缓存机制涉及到多个请求头字段,而且整个缓存机制的细节行为也存在各种情况的差异,譬如说什么时候访问本地缓存不发送请求,什么时候发送请求查看资源是否更新,获取 response 什么情况下更新缓存等。以前我对此一知半解只是笼统的知道一些概念,譬如 Cache-Control 可以控制缓存的时间和是否需要缓存,但是缓存过期后的行为,有缓存后浏览器是否有 http 请求都不甚了解。所以特地 google 下,此篇是对此的知识梳理。
协议概述
什么情况下可以使用本地缓存?譬如说我们用 get 方式请求了一个资源
http://mytest.domain.com/static/images/bg.png
,那么我们下次再请求这个图片资源的时候符合哪些条件可以使用本地缓存呢?http://mytest.domain.com/static/images/bg.png
,如果是http://mytest.domain.com/static/images/bg.png?t=12312321
就会发起新的请求,因为 url 不同。注1:上述任何提一个条件都可以被 cache-control extension 覆盖
注2:response header中不仅仅可以 Cache-Control: no-cache,还可以 Cache-Control: no-cache="Set-Cookie" 详见
如何计算本地缓存是否过期
浏览器是通过比较缓存剩余有效时间和当前缓存已存在时间来判断的:
response_is_fresh = (freshness_lifetime > current_age)
。freshness_lifetime
取值优先级次序如下列表所示(排在上面的优先级越高):注1;如果有多个重复的上述头,那么是非法的,视作 response(资源)过期
freshness_lifetime 计算(推测)规则:
规范并没有给出具体的算法,但是给出了最坏情况(but does impose worst-case constraints on their results),如果 response(资源)有 Last-Modified 头,那么推荐用从当前到lastmodified这个时间段的 10% 作为
freshness_lifetime
,并且 response(资源)的 current_age 如果已经超过24小时,必须在这个 response 上加上113 warn-code头。很少有浏览器实现了freshness_lifetime
的自助计算(推测),所以还是还是鼓励给出上述显式的1 - 3三种情况。current_age 计算规则:
泛泛来说就是 response(资源)在本地的驻足时间加上网络传输时间,因为网络传输时间的计算有多个条件,规范实在看的我头晕,所以具体计算规则详见规范
本地缓存过期,如何通过服务器验证缓存的是否依然有效(即304的情况)
首先,如果第一次的 response(资源)头中显示申明了一些禁止缓存的头(譬如:"no-store" or "no-cache" 等等),就不存在过期不过期的问题,因为这个资源不允许缓存。其次,过期缓存也不一定不可用,如果在断网或者第二次请求带上 max-stale 这个请求头,那么浏览器可以使用过期的缓存(masx-stale 表示在缓存过期后多少时间内浏览器依然可以使用缓存)。碰到过期缓存,浏览器可以发送一个条件请求(conditional request)。这个请求的 url 依然是第一次请求的 url,只是会带上些当前资源的一些信息,以供服务器验证这个缓存是否依然可用还是需要更新:
服务器会根据不同的条件请求头来验证资源,具体的行为详见规范,这里不细致展开。针对条件请求,服务器返回会有三种情况:
如果是一个304的返回,规范说这个返回可以更新本地缓存,更新策略分三种:
协议流程图
假设第一次请求一个资源,返回 header 里面带上如下字段:
Cache-Control: max-age=600
Last-Modified: Wed, 28 Aug 2013 10:36:42 GMT
ETag: "124752e0d85461a16e76fbdef2e84fb9"
抛开细枝末节的东西,那么第二次请求通常大致流程图如下:
特殊情况
当你去浏览器验证的时候可能会碰到一些特殊情况,就是缓存有效,但是你刷新浏览器依然发送的条件请求。其实是因为浏览器在请求头中加入了一些料,譬如: Cache-Control: max-age=0。你刷新的方式可以有很多种,譬如:按F5,按ctrl+F5,在地址栏按回车等等。这些不同的行为都会影响浏览器发送请求的行为。这里有一些参考《在浏览器地址栏按回车、F5、Ctrl+F5刷新网页的区别》
参考资料
rfc7234
The text was updated successfully, but these errors were encountered: