请教一下关于浏览器(HTTP)缓存的问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
xiaoz
1.03D

请教一下关于浏览器(HTTP)缓存的问题

  •  
  •   xiaoz Jul 25, 2019 2502 views
    This topic created in 2467 days ago, the information mentioned may be changed or developed.

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

    13 replies    2019-07-25 20:21:42 +08:00
    meik2333
        1
    meik2333  
       Jul 25, 2019   1
    etag 和 last-modified 至少要提供一个吧,不然无法判断照片是否被修改过。
    1KN6sAqR0a57no6s
        2
    1KN6sAqR0a57no6s  
       Jul 25, 2019 via Android
    因为你直接在地址栏输入的图片地址,用 img 标签加载试试。
    xiaoz
        3
    xiaoz  
    OP
       Jul 25, 2019 via Android
    @YuxiangLuo 但是你访问这张图片试试 https://cdn.xiaoz.me/wp-content/uploads/2019/07/snipaste_20190721_155819.png 也是直接访问图片,再次刷新是可以返回 304 的。
    Itanium
        4
    Itanium  
       Jul 25, 2019
    以 etag 为例,这个需要服务器告诉浏览器是否取缓存
    客户端存下 etag,然后在 headers 里加上 if-none-match 再把服务器给的 etag 传回去,如果图片没发生改变 etag 不会变,服务器返回 304 让浏览器从本地缓存取
    JK9993
        5
    JK9993  
       Jul 25, 2019
    chrome 缓存了也会返回 200
    Cynic222
        6
    Cynic222  
       Jul 25, 2019 via iPhone
    你要看是不是 from cache
    limuyan44
        7
    limuyan44  
       Jul 25, 2019
    你没发现这 2 个图片请求头和返回头都不一样吗
    gbin
        8
    gbin  
       Jul 25, 2019   1
    #5 说的对。
    如果 HTTP 响应头被设置了 `Cache-Control: max-age=6000`,在缓存的有效期内,也就是 6000 秒内,HTTP 请求不对缓存的资源做新鲜度校验,而是直接返回 200。如果你想每次都对缓存资源做新鲜度校验,那么你可以设置成 no-store (或者设置 must-revalidate ),no-store 的意思是不建议直接使用缓存而不是不使用缓存,这种情况下,HTTP 请求会配合 ETag + If-Modified 等多个请求头对资源校验,如果资源没有被更改服务器才会返回 304,告诉客户端资源没有被修改,可以直接取本地缓存。
    gbin
        9
    gbin  
       Jul 25, 2019   1
    @gbin #8 不建议直接使用缓存是 no-cache,no-store 是禁止使用缓存
    wszgrcy
        10
    wszgrcy  
       Jul 25, 2019 via Android
    有强制缓存和协商缓存
    gbin
        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 比对,如果都比对成功说明资源没有被修改,所以客户端直接取缓存。
    gbin
        12
    gbin  
       Jul 25, 2019
    另外还有一个点就是 #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 的请求头对图片做新鲜度校验。
    meik2333
        13
    meik2333  
       Jul 25, 2019   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 标签加载的话,你们两个的图片都是可以被缓存的。
    About     Help     Advertise     Blog     API     FAQ     Solana     841 Online   Highest 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 466ms UTC 21:34 PVG 05:34 LAX 14:34 JFK 17:34
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86