V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
3dwelcome
V2EX  ›  前端开发

有没有人觉得 http 缓存设计的很不合理?

  •  
  •   3dwelcome · 2022-01-24 10:25:17 +08:00 · 4738 次点击
    这是一个创建于 1037 天前的主题,其中的信息可能已经有所发展或是发生改变。

    一般来说,WEB 是一个 html 主页面,里面包含若干个 css/js 。正常 html 是不缓存,确保浏览器每次访问都是最新的内容(服务器返回 200 或者 304)。

    而 css/js 是时间策略缓存,也就是没过期之间(由 max-age 来定),浏览器压根不会向服务器发任何请求!就算 JS 代码有更新,短时间内用户也无法感知。

    为了破除这个限制,webpack 都会在 js/css 后面加上 hash ,来解决这个问题。

    那么问题来了,为什么 HTTP 不设计成,能一次性的向服务器请求 HTML 里所有 css/js 的最后更新时间( last-modified-time ),看看有哪些文件变动了,再针对性的获取呢? 这样 JS 就不用每次都改新文件名了。

    第 1 条附言  ·  2022-01-24 11:26:20 +08:00
    我提一下自己的解决方案,只要在 HTML 里修改一下就行。

    1. 在〈 head 〉里加入〈 meta name='file.js' cache-control-etag='hash'/〉
    2. 用〈 script src='file.js' etag='hash'〉
    3. 用〈 script src='file.js' last-modifed-time='utctime'〉

    三种方法任选之一,即可完美解决问题。可惜这种新规范没人愿意去推动。
    57 条回复    2022-01-27 17:24:04 +08:00
    cmdOptionKana
        1
    cmdOptionKana  
       2022-01-24 10:35:50 +08:00
    可能因为最初 http 发明时每一个 byte 的流量、每一次 IO 都需要尽量节省吧。
    NewYear
        2
    NewYear  
       2022-01-24 10:55:02 +08:00
    交流最好的方式是,不能只提问题,也要提解决方案。

    虽然你给了解决方案,说白了也是不可行的,需要浏览器支持,需要服务器支持,难难难,而且你这个就涉及到所有软件都会面临的问题(自动升级)。。。你说的“一次性查询”,是怎么定义的,每天第一次?每次打开浏览器第一次?每次打开此网页的一次?如何定义呢。

    就难度来说,JS 的开发者都有能力实现你所需要的这个功能,我举个例子,你服务器上可以有一个 json 的 list ,里面有每个 js 文件和日期,或者你用服务器语言自己定义一个动态的列表,浏览器有 localstorage (现在的浏览器没有不支持的)你也可以在里面放上一个 list ,然后在你任何想要“检查”的时候检查,然后版本号 /日期加入到 js 文件的 url 后面就可以了。

    相对而言,是不是自己写的兼容性又高,又能满足自己的各种个性化需求呢?

    不过说实话缓存这个东西确实是有点尴尬,我在服务器更新的 js 文件,大半年过去了,还能在同事电脑看到未修改前的版本,不过也是我没用心去处理,其实这些东西百度早有解决方案了。
    micean
        3
    micean  
       2022-01-24 10:59:49 +08:00   ❤️ 1
    “一次性的向服务器请求 HTML 里所有 css/js 的最后更新时间”

    那请求的策略是什么?
    3dwelcome
        4
    3dwelcome  
    OP
       2022-01-24 11:01:14 +08:00
    @cmdOptionKana
    @NewYear

    我以为 HTTP2.0 比较新,会变一下方法,结果查了一下,缓存方面完全没有变。

    js 加 hash 改名,其实就是变相破坏了浏览器原本的缓存策略。

    html 有设计 JS 文件内容强校验属性《 script src='vue.js' integrity='sha-256:hash'》, 但就是没有 ETAG 缓存属性《 script etag='hash'》或者 Last-Modified 属性。
    3dwelcome
        5
    3dwelcome  
    OP
       2022-01-24 11:03:04 +08:00
    @micean “那请求的策略是什么?”

    只要在 HTML 里告诉浏览器,js 文件的最后修改时间,或者是最新的 HASH ,那样文件名不用改名,也能获取最新文件。
    Biwood
        6
    Biwood  
       2022-01-24 11:03:09 +08:00
    这跟 html 、css 、js 没什么关系,而是 HTTP header 里的设置问题,你说的 webpack 加 hash ,那只是本地开发调试不方便配置 header 缓存策略,从而用最简单和原始的方法。凡是 html 能用的缓存策略,可以适用于任何经由 HTTP 传输的其他文件类型上面。
    serge001
        7
    serge001  
       2022-01-24 11:05:24 +08:00
    你上面说的方案不是已经很好了嘛:html 使用协商缓存(返回 200 或者 304 ),js ,css 使用强缓存(使用本地缓存),更新的时候更新 hash 即可,至于你说的:为什么 HTTP 不设计成,能一次性的向服务器请求 HTML 里所有 css/js 的最后更新时间( last-modified-time ),看看有哪些文件变动了,再针对性的获取呢?

    从实现的难度和灵活性来讲并没有比使用 hash 好很多吧?
    otakustay
        8
    otakustay  
       2022-01-24 11:06:52 +08:00
    HTTP2 下已经没有必要“一次性请求”这个事情了吧,反正都并发了,header 也有 HPack 压缩了。如果觉得需要 HTML 解析才能找到 JS/CSS 资源有个串行过程的话,用<link preload>,然后把 head 部分单独作为 chunk 吐出来,不要等 body 就行
    3dwelcome
        9
    3dwelcome  
    OP
       2022-01-24 11:09:53 +08:00
    @serge001 比如 HTML 里有 10 个 JS 和 CSS ,服务器有变动了,明明可以在 HTML 里通知浏览器的。

    只要设计有《 meta jsname='file.js' cache-control-etag='hash'》类似的语句就行。

    总比浏览器自己去访问十次服务器,对比 10 次 HASH ,浪费流量来的好吧。
    kop1989smurf
        10
    kop1989smurf  
       2022-01-24 11:13:54 +08:00
    我觉得有两方面的原因。

    主要原因是文件的“最后修改时间”变化,和文件重新读取并不是一个强逻辑关系。

    次要是有历史原因。忘记这个术语叫什么了,大概意思是“同样参数的 get ,返回值要一样”。
    mxT52CRuqR6o5
        11
    mxT52CRuqR6o5  
       2022-01-24 11:13:56 +08:00
    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Last-Modified
    有这个特性啊,你在 js/css 的 response 里声明不走强缓存,就可以走协商缓存了
    micean
        12
    micean  
       2022-01-24 11:13:57 +08:00
    @3dwelcome

    没区别啊,更新还是通过每次请求来判断。
    不想改文件名,也必须要有其他方式做到“不同值”,显然 hash 文件名是性能最高的方式吧
    浏览器做到最大限度的缓存,剩下的就交给 html 服务提供者自己了
    mxT52CRuqR6o5
        13
    mxT52CRuqR6o5  
       2022-01-24 11:16:00 +08:00
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Cache-Control
    总不能你自己想要协商缓存不想要强缓存,就禁止 web 标准添加强缓存的特性,禁止所有人使用强缓存的 feature 吧
    serge001
        14
    serge001  
       2022-01-24 11:17:01 +08:00
    @3dwelcome “浏览器自己去访问十次服务器,对比 10 次 HASH” 这句不是很明白,css 和 js 的缓存策略通常都是配置为强缓存的,max-age 会设置一个很大的时间,避免去重新请求
    3dwelcome
        15
    3dwelcome  
    OP
       2022-01-24 11:18:22 +08:00
    @mxT52CRuqR6o5 “有这个特性啊,你在 js/css 的 response 里声明不走强缓存,就可以走协商缓存了”

    不走强缓存,那用户每次刷新一下主页,HTML 有十个 js/css 文件,HTTPS 就会连续去请求十次!

    这在移动互联网时代,是很难接受的,没准哪个请求就卡住,拖慢了页面整体载入后腿。
    wanguorui123
        16
    wanguorui123  
       2022-01-24 11:20:53 +08:00
    max-age 是减少请求,Etag 是避免获取重复文件相当于 Hash ,Cache 与 ETag 组合使用比较好
    serge001
        17
    serge001  
       2022-01-24 11:21:27 +08:00
    至于你说的方案,对于引入的第三方 js 怎么处理?难道要请求 html 的服务器去请求一下第三方的服务器获取这个 js 文件的更新时间嘛
    mxT52CRuqR6o5
        18
    mxT52CRuqR6o5  
       2022-01-24 11:22:27 +08:00
    @3dwelcome 哦哦,没看清楚是要一次性是吧,那旧版 http 可能确实没法直接做到,不过不是还有 http2 吗,1 次和 10 次没多大区别了,http1 里搞这些可能难以避免 breaking change 吧
    mxT52CRuqR6o5
        19
    mxT52CRuqR6o5  
       2022-01-24 11:23:11 +08:00
    http1 的话也许可以尝试在业务层自行实现一次性的向服务器请求 HTML 里所有 css/js 的最后更新时间
    3dwelcome
        20
    3dwelcome  
    OP
       2022-01-24 11:31:13 +08:00
    @mxT52CRuqR6o5 “http1 的话也许可以尝试在业务层自行实现一次性的向服务器请求 HTML 里所有 css/js 的最后更新时间”

    我确实是这样处理的,还是觉得麻烦。

    直接修改 JS 文件嘛,如果不用 webpack ,每次还要用 ctrl+F5 刷新一下,真是累人。
    HeyWeGo
        21
    HeyWeGo  
       2022-01-24 11:33:26 +08:00
    @kop1989smurf #10 幂等性?
    3dwelcome
        22
    3dwelcome  
    OP
       2022-01-24 12:04:59 +08:00
    @serge001 "至于你说的方案,对于引入的第三方 js 怎么处理?"

    引入第三方 JS ,就更需要我说的这个方案了。

    举个例子,假设第三方 JS 被黑,很可能导致你主网站用户的 cookie ,全部被恶意泄漏。

    能避免这样方法,就只有给 script 标签加上 hash ,做文件的内容二次校验。这和我说的标签加 ETAG ,是一回事。
    lujjjh
        23
    lujjjh  
       2022-01-24 13:15:10 +08:00   ❤️ 1
    0. 我理解你的方案可以用 querystring 里加 hash 做 cache busting ,同时加上 integrity 校验内容 hash 实现。
    1. HTTP cache 不一定是 end-to-end 的,中间任意七层节点(比如 CDN 节点)都可以缓存,你还需要考虑你的这个机制怎么让中间节点知道某个资源缓存失效,上面的方案可能导致中间节点出现脏缓存。
    2. 前端发布不是原子操作,发布过程中至少需要有两个版本共存,避免用户访问的时候下载到不同版本的资源。如果文件名不变,理论上是做不到无损发布的,这也是为什么现在基本没有人靠 querystring 来做 cache busting 了,基本都是在文件名里加 hash 。
    id4alex
        24
    id4alex  
       2022-01-24 13:26:03 +08:00
    每次工程启动保存一个 unixtime, 然后资源文件 Link 加上?version=${unixtime}
    wonderfulcxm
        25
    wonderfulcxm  
       2022-01-24 13:37:48 +08:00 via iPhone
    这跟 html 或 css/js 没关系吧,取决于服务器的响应头,如果你愿意,可以修改响应头,css/js 可以用 html 一样的缓存策略。
    Jooooooooo
        26
    Jooooooooo  
       2022-01-24 13:46:30 +08:00
    确实是历史原因.

    可以再搜搜 http cache poison
    3dwelcome
        27
    3dwelcome  
    OP
       2022-01-24 13:46:44 +08:00
    @wonderfulcxm "如果你愿意,可以修改响应头,css/js 可以用 html 一样的缓存策略。"

    我本地测试用一样的策略啊,都是 max-age=0 ,本地流量无所谓,这样浏览器会自动获取新数据。

    但是给客户用 max-age=0 ,页面有多少个 css 和 js ,就会多出多少条 HTTPS 链接,这设计显然不太合理。

    所以我才说有缺陷。浏览器既然能识别 script 标签的 integrity 做内容校验,那顺便判断 ETAG ,节省网络资源的新 HTTPS 链接,就是举手之劳。
    Pastsong
        28
    Pastsong  
       2022-01-24 13:47:46 +08:00
    serviceWorker 解君愁
    3dwelcome
        29
    3dwelcome  
    OP
       2022-01-24 13:59:50 +08:00
    @lujjjh “前端发布不是原子操作,发布过程中至少需要有两个版本共存”

    这样一想,确实也有点道理。

    如果一个新版 JS 要强制更新,万一有几十万个 Web 用户,同时下载 JS ,给服务器的压力也不少。

    允许多个版本同时存在,渐进更新就没这个问题。
    yaphets666
        30
    yaphets666  
       2022-01-24 14:57:07 +08:00   ❤️ 2
    我明白了兄弟,你是要干翻现有前端体系
    yuzo555
        31
    yuzo555  
       2022-01-24 15:12:07 +08:00   ❤️ 1
    HTML 和 JS/CSS 并不一定是同一个提供者,而且一个网站引用的 JS/CSS 很有可能来自不同的提供者,比如同站和站外,比如不同的第三方 CDN ,甚至是同一个公司不同的团队(比如 A 产品团队需要使用到 B 产品,直接用 B 产品现成的 JS )。

    统一提供一个接口获取更新时间比现行方案麻烦太多了,特别是如果某个 JS/CSS 中间代理、CDN 、负载均衡的套娃比较多,你根本不知道找谁确认更新时间。

    如果是你说的这种,HTML 和 JS/CSS 属于同一个提供者、同一个服务器的情况,这个提供者自己在服务器端修改响应头就可以了,响应头控制得好,比你的方案能少一次请求。

    也许你担心的是在缓存期内突然来了个 bug 需要紧急修复,这种属于特殊场景,加 hash 的方案就挺合适的,怎么也比你的方案要简单。

    “就会多出多少条 HTTPS 链接”,HTTPS 连接都是复用的,不需要每次都重新来一遍,没你想的那么耗能。而且如你所说,如果文件没更新,返回 304 也非常省流。
    0ZXYDDu796nVCFxq
        32
    0ZXYDDu796nVCFxq  
       2022-01-24 15:30:01 +08:00
    cache-control + hash 是最符合 KISS 的
    甚至,cache-control 都够了
    ch2
        33
    ch2  
       2022-01-24 15:48:04 +08:00 via iPhone
    你可以先发 head 请求,响应头里会告诉你上次变更的时间
    ch2
        34
    ch2  
       2022-01-24 15:55:02 +08:00 via iPhone   ❤️ 1
    @3dwelcome pwa 可以解决这个问题,前端自主拦截请求,使用本地缓存,这样用户刷新就不会多发 10 个请求了
    otakustay
        35
    otakustay  
       2022-01-24 19:05:32 +08:00
    或者换个角度,用 resource integrity 来控制浏览器缓存( integrity 和 cache 里的一样就用,不一样就请求再检查 integrity )可能是更好的实现
    ryd994
        36
    ryd994  
       2022-01-25 02:19:58 +08:00 via Android
    这不就是加 hash 吗?你绕了一圈还不是回来了。
    服务器直接把你说的 last-modify 的 tag 加到 css 的 URI 里,你看你得到了什么?
    比如 example.com/static/lastmodify_12345678/abc.css

    Nginx 识别处理这种 URI 很容易
    NewYear
        37
    NewYear  
       2022-01-25 08:44:23 +08:00
    楼主说的第二条,现在浏览器已经支持了,link 和 script 标签都支持 integrity 就是填入文件的 hash ,这样还能跨网站缓存(意思是 A 网站缓存过这个文件,B 网站就直接使用,而且 A 和 B 的 JS 文件的 URL 是截然不同的):
    2. 用〈 script src='file.js' etag='hash'〉

    就像我上面 2 楼回复的一样,你只是在“提建议”,却不给“解决办法”,你自己也不愿意动手写,自己写其实这玩意是很简单的一个事情啊!然后你又没有去找资料,明明浏览器已经支持了,你还在说没人推动,怎么就没人推动实现呢,明明是已经实现了的!!!就等着你去用的!

    你可以看一下,我回复了 2 条内容,都是有明确的解决办法,你提了 N 个问题,有 N 个想法,却只是在“我想要”的层面。我的方法 1 ,如果是你的网站,那完全是在控制范围内,方法 2 ,是跨域使用 js 文件,你还想要继续讨论得到方法 3 吗。。。

    好吧,那我提一个方法 3 ,随便一个能读写文件的语言,都能实现自动生成时间属性、时间后缀、hash 后缀并写入你的 html 文件,

    请结贴,哦哦你想要偷懒,让 HTTP 服务器自动干这个事?其实也完全没问题啊,都是开源的,改一改一定能实现的。等等……你不会是想要“提一个意见,天下都听我的按我的方案来!”这样的吧。这样的话就尴尬了,毕竟谁也不缺一个想法啊。。
    3dwelcome
        38
    3dwelcome  
    OP
       2022-01-25 09:20:04 +08:00
    @NewYear integrity 是内容强校验 hash ,仅仅只是确保内容是否正确。

    integrity hash 和缓存里的 etag hash 是完全隔离的,又不能相互调用。

    你说让我用,问题是这样写,没法用啊。我觉得你搜到的 cache ,应该是 cdn 的 cache,不是浏览器的 cache 。
    3dwelcome
        39
    3dwelcome  
    OP
       2022-01-25 09:29:33 +08:00
    @ryd994 “服务器直接把你说的 last-modify 的 tag 加到 css 的 URI 里,你看你得到了什么?”

    就是不希望加在 URI 里。问题的核心,我就希望只请求一个 HTML ,里面包含了足够的 js/css 校验信息给浏览器。

    浏览器本地匹配完缓存资源后,如果没有新资源更新(属于常态),那后续没有任何的服务器 URL 请求!

    我就想把这 css/js 校验流量,给节省下来,在我看来是完全多余的。HTTPS 返回 304 是很快,可是 DNS 解析,有时候会卡半天,属于客户端不可控因素。
    NewYear
        40
    NewYear  
       2022-01-25 10:03:02 +08:00
    @3dwelcome

    “integrity 是内容强校验 hash ,仅仅只是确保内容是否正确。”
    如果浏览器不按 integrity 做缓存,那我觉得才叫奇葩,为什么呢,我认为这个属性重要的功能应该是 2 项,1.防止执行未知的 js 文件内容,带来了安全的效果; 2.跨网站做缓存(例如大家都调用了 vue2.0 ,只要第一个网站加载过,第二个网站就再也不用请求这个 js 文件了)。

    但是我们之所以写 script 标签,写 src ,99%的目的是什么呢?最大的目的仍然是“我要执行这个文件里面的 js 语句”,而不是“我只是为了检验 src 的 js 文件是否符合预期”。



    重点:我做了测试,Firefox 会按照 integrity 做缓存,新的 url 但是 integrity 相同,不会发出请求,Chrome 我就不测了。
    ryd994
        41
    ryd994  
       2022-01-25 10:12:27 +08:00 via Android
    @3dwelcome 1. CSS 的 URI 是不是 HTML 的一部分?
    如何你设置 max-age 为最长时间,那么浏览器不需要再发请求 revalidate 。也就实现了你的目的。

    你建议 script src='file.js' last-modifed-time='utctime
    这和 script src='utctime/file.js'
    有什么区别?

    你还可以使用 stale-while-revalidate ,浏览器会立刻使用 cache ,即使 cache 已经过期。然后再在后台和服务器更新。
    ryd994
        42
    ryd994  
       2022-01-25 10:12:56 +08:00 via Android
    *如果 你设置 max-age 为最长时间
    ryd994
        43
    ryd994  
       2022-01-25 10:22:54 +08:00 via Android
    而且你还可以使用 immutable
    3dwelcome
        44
    3dwelcome  
    OP
       2022-01-25 11:02:18 +08:00
    @ryd994 “你建议 script src='file.js' last-modifed-time='utctime
    这和 script src='utctime/file.js'
    有什么区别?”

    上面一句浏览器可以本地缓存比对,如果文件缓存里有,就不需要发一条 URL 请求去服务器。
    下面一句浏览器必须去访问一下服务器,哪怕返回的是 304 。

    “如果 你设置 max-age 为最长时间”
    就是设置 max-age 才会导致这种不合理的情况发生,在 max-age 没到期前,浏览器默认就是 CSS/JS 有效的,和服务器不同步。
    ryd994
        45
    ryd994  
       2022-01-25 13:42:09 +08:00
    @3dwelcome 1. “上面一句浏览器可以本地缓存比对,如果文件缓存里有,就不需要发一条 URL 请求去服务器。”这本就是浏览器的不正确实现。标准最初定义的是 max-age 过期前不必 revalidate 。但是由于各大浏览器都是这样实现,所以最终标准妥协了,变成了 max-age 前需要 revalidate 。

    所以,后来加入了两个 cache-control 选项:
    stale-while-revalidate ,浏览器立刻使用 cache ,但在后台 revalidate
    immutable ,浏览器彻底相信 max-age ,max-age 前完全不 revalidate

    如果你在 utctime/file.js 上使用这两个选项之一,就不会有你说的问题。
    3dwelcome
        46
    3dwelcome  
    OP
       2022-01-25 13:59:02 +08:00
    @ryd994 你还是没理解我的意思,我是说 revalidate 就完全没有存在的必要!

    如果 HTML 文件里有 JS 的 hash 值,那么问题就很简单。

    * hash 和缓存一样,那浏览器获取了 HTML 后,就无需发起任何后续的网络连接。
    * hash 和缓存不一样,那浏览器就直接去取最新的 JS 。

    这样逻辑就清晰多了。浏览器去问服务器,某某 JS 文件要不要更新,本身就是一件多余的操作。
    3dwelcome
        47
    3dwelcome  
    OP
       2022-01-25 14:26:40 +08:00
    @NewYear 我用 Chrome 实测没测出来。

    官方没任何文档说 integrity 和浏览器本地缓存有什么必然联系。可能只和第三方 CDN 刷新机制有关系。

    Chrome 下不匹配 integrity ,就是直接阻止脚本运行,弹出 The resource has been blocked 。

    至于缓存没任何区别。
    NewYear
        48
    NewYear  
       2022-01-25 16:44:13 +08:00
    @3dwelcome

    我不知道你怎么测试的,我实测 Chomre 97.0.4692.99 正式版,是会形成缓存。单个页面单个 script 标签,第一次打开后会下载 js 文件,切换成别的 URL ,不改 integrity ,再访问不会产生新的通讯。

    抓包软件上看得清清楚楚,明明白白。

    我已经表达得很清楚了,你还在疯狂的反驳,测试数据也不正确,自写 JS 也不干(明明很简单就能实现完全可控的方式),不要回复我了,帮你搜索,帮你测试,最后还是无效沟通,这个贴浪费我太多时间了,再见。
    ryd994
        49
    ryd994  
       2022-01-25 17:35:44 +08:00 via Android
    @3dwelcome 你看到我说的 immutable 选项了吗?你喜欢你可以把你所有静态资源设置 immutable ,然后把你的 hash 直接嵌在 URI 里。这样每个 URI 确实就是 immutable 的。

    楼上的实测结果你也是完全没看,你如果认为 immutable 解决不了你的问题,拿出实测数据便是。

    你真是好大的口气,明明是有现成的解决办法,你非要把之前的标准推翻用你的新标准。
    为什么标准变成了现在这样,这不是你能决定的问题。你一直在以“如果互联网让我设计”为前提。然而互联网从一开始就不是谁设计,谁规定的。ietf 也只是参考性的记录。实际上是几个开路人说,诶,咱们就这么办。然后用的人多了,事实上就形成了通行的标准。
    HTTP 缓存,不管最初的设计如何,各大浏览器用了这个标准,各大 Web 服务器用了这个标准,那这个标准就是标准。

    如果你觉得你的标准可以推翻现有的标准,talk is cheap 。你需要有可用的代码实现,然后写一篇论文来证明你的标准,然后可以提交 rfc 。good luck
    3dwelcome
        50
    3dwelcome  
    OP
       2022-01-25 18:26:49 +08:00
    @NewYear “我不知道你怎么测试的”

    我用的是 chrome96, 不管改不改 integrity ,只要 max-age=0 ,资源过期了,浏览器就必定会向服务器发起新连接。

    不是你说的,浏览器就直接不请求了。

    这个测试结果是符合预期的。

    integrity 改了,只会让你的资源加载失败,和网络缓存真没关系。不信你可以把相关的搜索资料给贴出来。
    3dwelcome
        51
    3dwelcome  
    OP
       2022-01-25 18:33:00 +08:00
    @ryd994 你说的 immutable 就是彻底相信 max-age ,js 在有效期内是不会变的。

    可是 js 内容改动是很正常的一件事情,为什么要去设置永恒不变呢?

    这里讨论的是新思路,只要思路对了,用 JS 在 localStroage 里自己管理缓存,代码实现是很容易,回个贴不需要那么激动。
    NewYear
        52
    NewYear  
       2022-01-25 19:28:07 +08:00
    最后申明,不要 @我了,我甚至连个程序员都不是,业余程序员都算不上,但是我遇到这个困扰的时候起码能找到 2-3 种解决办法。

    给你最后一点建议,在你发挥超能力改变这个世界之前,请你先了解它,然后尝试一下有没有办法用起来,如果实在是不行,我真心的期待你有能力改变它。不管是钱也好、超能力也好、其他能力也好,我希望你有这个能力。

    而你现在发起讨论,但又过于偏执,浪费的不光是你的时间,还有别人有限的生命,而且还是浪费在抬杠上面。


    “只要 max-age=0 ,资源过期了”,这种参数确定不是为了抬杠而设计的吗?
    3dwelcome
        53
    3dwelcome  
    OP
       2022-01-25 20:06:50 +08:00
    @NewYear 设置 max-age=0 肯定不是抬杠,如果大于 0 ,那么浏览器就自动默认资源在有效期内,是不会发起网络请求的。

    这时候就算你把验证的 integrity 值给修改了,network 面板也不会有新的请求发起。

    唯一变化就是资源认证不通过,加载失败。
    ryd994
        54
    ryd994  
       2022-01-26 01:46:07 +08:00 via Android
    @3dwelcome 你的智商只能两句话看懂一句话,看完一句忘一句吗?
    你自己提议加上 hash ,那把 hash 加到 URI 里之后,这个 URI 是不是就是 immutable 的?难不成你同一个 hash 还能变?

    和你讨论真是浪费生命。


    而你现在发起讨论,但又过于偏执,浪费的不光是你的时间,还有别人有限的生命,而且还是浪费在抬杠上面。
    3dwelcome
        55
    3dwelcome  
    OP
       2022-01-26 03:57:52 +08:00
    @ryd994 "你自己提议加上 hash ,那把 hash 加到 URI 里之后"

    我说的 hash 是指 ETAG ,是为了去通知浏览器让老资源过期,重新获取新资源。

    和你说的“把 hash 加到 URI“完全是两回事。

    我为什么要把资源设置成永恒不变呢?资源明明已经失效了!就想让浏览器把老资源给删了。
    VagabondH
        56
    VagabondH  
       2022-01-27 17:21:33 +08:00   ❤️ 1
    问题是 http 协议不负责 html 的解析,解析 html 的是浏览器
    就因为 http 本身简单,才能这么大范围的使用,如果各种场景都适配优化,那它本身就太复杂了
    VagabondH
        57
    VagabondH  
       2022-01-27 17:24:04 +08:00
    我觉得你的标签上加 cache 属性的方案不但没有解决任何问题,还让缓存这个东西依赖上 script / link 标签了,变得更复杂了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1020 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 20:55 · PVG 04:55 · LAX 12:55 · JFK 15:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.