
比如这张图片: https://f002.backblazeb2.com/file/test-imgurl/imgs/2019/07/085f80437d5da3bd_thumb.jpg 是存放在 B2 的,已经设置了Cache-Control: max-age=6000,但是发现浏览器每次刷新都是返回的 200 状态码,而不是 304,浏览器并没有缓存这张图片,这是哪个 header 影响导致的呢?还是其它原因?

1 meik2333 Jul 25, 2019 etag 和 last-modified 至少要提供一个吧,不然无法判断照片是否被修改过。 |
2 1KN6sAqR0a57no6s Jul 25, 2019 via Android 因为你直接在地址栏输入的图片地址,用 img 标签加载试试。 |
3 xiaoz OP @YuxiangLuo 但是你访问这张图片试试 https://cdn.xiaoz.me/wp-content/uploads/2019/07/snipaste_20190721_155819.png 也是直接访问图片,再次刷新是可以返回 304 的。 |
4 Itanium Jul 25, 2019 以 etag 为例,这个需要服务器告诉浏览器是否取缓存 客户端存下 etag,然后在 headers 里加上 if-none-match 再把服务器给的 etag 传回去,如果图片没发生改变 etag 不会变,服务器返回 304 让浏览器从本地缓存取 |
5 JK9993 Jul 25, 2019 chrome 缓存了也会返回 200 |
6 Cynic222 Jul 25, 2019 via iPhone 你要看是不是 from cache |
7 limuyan44 Jul 25, 2019 你没发现这 2 个图片请求头和返回头都不一样吗 |
8 gbin Jul 25, 2019 #5 说的对。 如果 HTTP 响应头被设置了 `Cache-Control: max-age=6000`,在缓存的有效期内,也就是 6000 秒内,HTTP 请求不对缓存的资源做新鲜度校验,而是直接返回 200。如果你想每次都对缓存资源做新鲜度校验,那么你可以设置成 no-store (或者设置 must-revalidate ),no-store 的意思是不建议直接使用缓存而不是不使用缓存,这种情况下,HTTP 请求会配合 ETag + If-Modified 等多个请求头对资源校验,如果资源没有被更改服务器才会返回 304,告诉客户端资源没有被修改,可以直接取本地缓存。 |
10 wszgrcy Jul 25, 2019 via Android 有强制缓存和协商缓存 |
11 gbin Jul 25, 2019 你给的两张图片为什么返回的值一个是 200 一个是 304? 这是因为两张图片的 Request Headers 中设置了 max-age=0,这是客户端告诉服务器本地缓存过期时间是 0,但是这并不是说客户端不能缓存,而是说每次请求都需要做新鲜度校验,如果资源没有被修改就返回 304 客户端取本地缓存,否则返回 200。第一张图片服务器没有返回 ETag 标志,再次请求的时候客户端无法比对成功,所以返回了 200 (猜测是后端动态生成的缩略图?),第二张请求时返回了 ETag 标志,再此请求时使用 if-none-match 和 ETag 比对,if-modified-since 和 last-modified 比对,如果都比对成功说明资源没有被修改,所以客户端直接取缓存。 |
12 gbin Jul 25, 2019 比如 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 Jul 25, 2019 @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 标签加载的话,你们两个的图片都是可以被缓存的。 |