比如这张图片: https://f002.backblazeb2.com/file/test-imgurl/imgs/2019/07/085f80437d5da3bd_thumb.jpg 是存放在 B2 的,已经设置了Cache-Control: max-age=6000
,但是发现浏览器每次刷新都是返回的 200 状态码,而不是 304,浏览器并没有缓存这张图片,这是哪个 header 影响导致的呢?还是其它原因?
1
meik2333 2019-07-25 18:10:26 +08:00 1
etag 和 last-modified 至少要提供一个吧,不然无法判断照片是否被修改过。
|
2
1KN6sAqR0a57no6s 2019-07-25 18:14:10 +08:00 via Android
因为你直接在地址栏输入的图片地址,用 img 标签加载试试。
|
3
xiaoz OP @YuxiangLuo 但是你访问这张图片试试 https://cdn.xiaoz.me/wp-content/uploads/2019/07/snipaste_20190721_155819.png 也是直接访问图片,再次刷新是可以返回 304 的。
|
4
Itanium 2019-07-25 18:52:45 +08:00
以 etag 为例,这个需要服务器告诉浏览器是否取缓存
客户端存下 etag,然后在 headers 里加上 if-none-match 再把服务器给的 etag 传回去,如果图片没发生改变 etag 不会变,服务器返回 304 让浏览器从本地缓存取 |
5
JK9993 2019-07-25 18:55:39 +08:00
chrome 缓存了也会返回 200
|
6
Cynic222 2019-07-25 19:05:18 +08:00 via iPhone
你要看是不是 from cache
|
7
limuyan44 2019-07-25 19:11:11 +08:00
你没发现这 2 个图片请求头和返回头都不一样吗
|
8
gbin 2019-07-25 19:29:56 +08:00 1
#5 说的对。
如果 HTTP 响应头被设置了 `Cache-Control: max-age=6000`,在缓存的有效期内,也就是 6000 秒内,HTTP 请求不对缓存的资源做新鲜度校验,而是直接返回 200。如果你想每次都对缓存资源做新鲜度校验,那么你可以设置成 no-store (或者设置 must-revalidate ),no-store 的意思是不建议直接使用缓存而不是不使用缓存,这种情况下,HTTP 请求会配合 ETag + If-Modified 等多个请求头对资源校验,如果资源没有被更改服务器才会返回 304,告诉客户端资源没有被修改,可以直接取本地缓存。 |
10
wszgrcy 2019-07-25 20:04:18 +08:00 via Android
有强制缓存和协商缓存
|
11
gbin 2019-07-25 20:05:10 +08:00
你给的两张图片为什么返回的值一个是 200 一个是 304?
这是因为两张图片的 Request Headers 中设置了 max-age=0,这是客户端告诉服务器本地缓存过期时间是 0,但是这并不是说客户端不能缓存,而是说每次请求都需要做新鲜度校验,如果资源没有被修改就返回 304 客户端取本地缓存,否则返回 200。第一张图片服务器没有返回 ETag 标志,再次请求的时候客户端无法比对成功,所以返回了 200 (猜测是后端动态生成的缩略图?),第二张请求时返回了 ETag 标志,再此请求时使用 if-none-match 和 ETag 比对,if-modified-since 和 last-modified 比对,如果都比对成功说明资源没有被修改,所以客户端直接取缓存。 |
12
gbin 2019-07-25 20:19:35 +08:00
另外还有一个点就是 #2 说的,为什么你直接浏览器输入 URL 和使用 img 标签呈现效果不一样,
比如 https://0x400.com/2019-07-10-lc-67-add-binary.html 这个连接中有一张图片,如果你直接刷新页面你会看到图片是 from disk 或者 from cache,也就是命中缓存了,此时返回的就是 200. 但是如果你直接在浏览器中输入图片的 url,你会发现返回的是 304,这就是因为 Chrome 的 Reload 操作会主动携带 max-age=0 的请求头对图片做新鲜度校验。 |
13
meik2333 2019-07-25 20:21:42 +08:00 2
@YuxiangLuo #2
@JK9993 #5 @gbin #11 他们说的对,Chrome 如果本地缓存了,状态是 200 (from disk cache) 或者 200 (from memory cache),在 Chrome 中如果直接通过 URL 打开图片的话,会在 Request 中添加 cache-control: max-age=0 来让缓存不生效( https://superuser.com/questions/313131/how-do-i-stop-chrome-sending-cache-control-max-age-0-when-i-hit-enter ),因此如果需要测试 cache-control 是否生效的话,需要用 img 标签加载。 然后就是为什么他是 304 你是 200 的问题了,这个就是我刚才说的,因为你没有给 etag 和 last-modified。但是如果使用 img 标签加载的话,你们两个的图片都是可以被缓存的。 |