浏览器缓存策略详解
响应头字段
如何缓存以及采取那种缓存策略,都要由服务器首先告诉浏览器。即在浏览器首次发出请求后,服务器发送给浏览器的响应头字段如下——
1. Cache-Contorl
Cache-Control,即缓存策略,是浏览器读取缓存策略第一站,这个字段告诉了浏览器我们应该采取那种缓存策略——
- private 仅允许客户端浏览器缓存
- public 代理服务器和客户端浏览器都可以缓存
特别的值,
3. max-age:时间(秒),指定浏览器本地缓存数据的时间。
max-age和private或public可以同时组合存在,例如
Cache-Control: max-age:3000,public
4. no-cache 不使用“本地计时缓存”,但不影响使用“协商缓存”
2. date
既然指定了缓存多久,那么,肯定要记录下当前请求的时间呀,这样才能开始缓存,并计算出什么时候到期嘛。
所以,服务器会在返回的响应中用date字段存下当前的时间提供给浏览器比对。实际上使用Cache-Control:max-age:x...
补充一些结论:
我现在的问题是,如果配置了max-age 10分钟,must-revalidate,同时又有etag。此时我有一张图片在10分钟以内(没过期),但是服务器的etag改了,那么这张图片会立即被刷新,还是等到10分钟以后被刷新
在HTTP缓存策略中,当同时配置了max-age和ETag时,即使资源在max-age指定的期限内(例如10分钟),只要服务器端资源的ETag发生了改变,客户端仍然会在下一次请求时发送If-None-Match头部与服务器进行验证。服务器会根据收到的If-None-Match头中的ETag值与当前资源的实际ETag进行比较:
如果服务器发现ETag匹配(即资源没有改变),则返回304 Not Modified状态码,指示客户端可以继续使用缓存的图片。
如果服务器发现ETag不匹配(即资源已经更新),则会返回200 OK状态码,并附带新的图片内容。
同时,如果响应头还包含了Cache-Control: must-revalidate指令,这意味着在缓存过期之前,浏览器必须在使用缓存前先向服务器验证资源是否仍然有效。因此,在这种情况下,一旦服务器的ETag发生变化,无论max-age设置的时间长短如何,客户端都会立即发起条件性请求来验证资源,并根据服务器响应的结果决定是否刷新图片内容。
所以must-revalidate不是控制在本地缓存失效后向服务器重新验证,而是使用本地缓存前就会先验证对吗?注意我说的先后顺序,之前验证和之后验证效果是不一样的
是的,您的理解是正确的。must-revalidate 指令确实是在客户端尝试使用本地缓存内容 之前 强制向服务器进行验证。
具体来说,当一个响应头部包含 Cache-Control: must-revalidate 时,这意味着在缓存内容到期(即过期或已达到 max-age)之后,以及在任何情况下(包括在缓存内容仍在有效期内),客户端在使用存储的缓存副本前必须先与原始服务器通信以确认资源是否仍然有效。
即使资源未过期(比如还在10分钟的max-age之内),如果同时存在ETag并且服务器端资源的ETag已经改变,客户端在发起请求时会携带 If-None-Match 请求头,并且服务器将基于这个请求头中的 ETag 进行对比。如果发现不匹配,则服务器会返回更新后的资源,而不是让客户端继续使用旧的缓存版本。
总之,must-revalidate 确保了无论何时,在使用缓存内容之前都会执行一次有效性检查。
[查看全文]使用javascript生成指定区间的随机数
管〕Blue_sdo 13:04:26
我们都知道,js内置的随机数函数Math.random(),可生成[0,1)之间的随机数(包括0不包括1)
管〕Blue_sdo 13:05:09
即0<=Math.random()<1
管〕Blue_sdo 13:05:32
如果我们期待它生成从m到n之间的随机数
管〕Blue_sdo 13:05:49
即m<=生成的随机数<n
管〕Blue_sdo 13:06:07
我们应该要想办法配凑不等式
管〕Blue_sdo 13:07:25
首先,可以想到的是,如果在0<=Math.random()<1这个不等式上两边乘上n
管〕Blue_sdo 13:08:12
可以得到0<= Math.random()*n < n
管〕Blue_sdo 13:08:41
这样我们好像可以拿到0到n之间的随机数
管〕Blue_sdo 13:09:15
如果两边再加上m的话
管〕Blue_sdo 13:09:44
有m<= Math.random()*n +m < n+m
管〕...