有没有人觉得 http 缓存设计的很不合理? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
3dwelcome
V2EX    前端开发

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

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

    一般来说,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     Solana     2807 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 06:14 PVG 14:14 LAX 22:14 JFK 01:14
    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