• 请不要在回答技术问题时复制粘贴 AI 生成的内容
helee9199
V2EX  ›  程序员

js 有清除缓存的方法么

  •  
  •   helee9199 · Apr 28, 2022 · 7369 views
    This topic created in 1653 days ago, the information mentioned may be changed or developed.

    医院项目 项目有时修改到 js 后 替换到生产环境 有时有效 有时无效 清理缓存后则会好 但又不太好每次都让 user 清理缓存,他们也不一定会 所以有办法 清理缓存的方法么 目前想的是写到到登录入口 登录成功后就清理缓存 保证每次登录后是没有缓存的

    78 replies  •  2022-04-30 23:34:58 +08:00
    zingwu
    zingwu
    Apr 28, 2022
    1
    我们用的 umi ,每次更新打包完 hash 值变了会刷新
    3dwelcome
    3dwelcome
    Apr 28, 2022
    3
    这个 JS 没生效,一般都是服务器没有配置好。JS 没过期,自然是不会重新下载一次的。

    可以参考一下我以前的发帖,/t/830203
    WeiYuanStudio
    WeiYuanStudio
    Apr 28, 2022
    4
    打包 hash 后缀可解
    helee9199
    helee9199
    OP
    Apr 28, 2022
    5
    @3dwelcome emm 因为项目比较老,我们更新项目的方式还比较传统. 量大的时候就给完整包
    不涉及后台 jar 的时候.就单独给差异进行替换
    所以没有具体的某个页面去清缓存
    目前就希望每次登录的时候整个项目清缓存
    不知道那些清缓存插件是怎么实现的
    希望有个接口 调一下就能实现
    yunying
    yunying
    Apr 28, 2022
    6
    让用户浏览器安装插件跟让用户手动清楚缓存没什么区别,治标不治本。还是得对前段所有静态资源做缓存管理,根据开发成本和场景,可前后端都做或者单做其中一端看看能不能解决
    itechify
    itechify
    Apr 28, 2022❤️10
    7
    <a href="javascript:alert('清除成功');">清除缓存</a>
    helee9199
    helee9199
    OP
    Apr 28, 2022
    8
    @yunying
    老项目 老技术 不知道有什么方案可以解决
    可以说点关键字我搜索下么?
    elevioux
    elevioux
    Apr 28, 2022 via Android
    9
    js 地址加版本号?
    helee9199
    helee9199
    OP
    Apr 28, 2022
    10
    @elevioux 这个情况之能解决一个页面呀 ,项目那么多页面 都有引乱七八糟的 js 啥的 不太好实现
    目前只求能一次性清理项目页面缓存
    hgc81538
    hgc81538
    Apr 28, 2022
    11
    script_1.js?<script_1.js 在文件系統的最後修改 unixtime>
    script_2.js?<script_2.js 在文件系統的最後修改 unixtime>

    e.g. script_1.js?1651144341
    bearice
    bearice
    Apr 28, 2022
    12
    难道不能干脆不缓存么?反正是内部访问,那点儿量也不至于说不缓存就能咋样。
    helee9199
    helee9199
    OP
    Apr 28, 2022
    13
    @bearice 怎样不缓存呢
    就是想不缓存
    比如有个 bug 我改了 js 我们目前是把这个 js 拿去替换文件
    结果护士发现 没生效, 然后一沟通教他清缓存 ,然后就好了
    但是这不是个办法, 所以才想说如何清缓存 或者不缓存.
    bearice
    bearice
    Apr 28, 2022
    14
    an1ig
    an1ig
    Apr 28, 2022
    15
    响应头 Cache-Control: no-store
    ClericPy
    ClericPy
    Apr 28, 2022
    16
    别折腾 no-cache

    比较简单的方案前面提到了, js cdn 刷新了以后, 带冗余参数 ?v=xxxx, 这里的 xxxx 一般不用时间戳, 就用 js 计算出来的 md5 就行了. 不过后端得跟着一起发版...

    话说缓存这东西不是走 etag 的么
    Xhack
    Xhack
    Apr 28, 2022❤️2
    17
    alter("缓存清楚成功")
    ClericPy
    ClericPy
    Apr 28, 2022
    18
    @ClericPy 上面说错, 后端不一定要发版, 前后端隔离 HTML 也是前端项目的话就没事了

    虽然还是习惯 etag 什么的
    Yamdr
    Yamdr
    Apr 28, 2022
    19
    <script src="xxx.js?v=7"></script>
    Yamdr
    Yamdr
    Apr 28, 2022
    20
    <script src="xxx.js"></script>

    加上一个版本号
    <script src="xxx.js?ver=数字"></script>
    ImmerTry
    ImmerTry
    Apr 28, 2022
    21
    遇到和题主一样的问题
    Osk
    Osk
    Apr 28, 2022
    22
    不想动太多就向楼上的那样给 url 加 hash, 浏览器就会重新请求新文件了
    gamexg
    gamexg
    Apr 28, 2022
    23
    在根目录建立不同版本的不同路径
    即把原来这样的 url http://www.abc.com/web1.html 改为 http://www.abc.com/版本号 /web1.html 或 改为 http://版本号.www.abc.com/web1.html 。
    登录页面跳转到最新版本地址。
    gamexg
    gamexg
    Apr 28, 2022
    24
    另外,Service Workers 可能也能实现需求,印象这个可以拦截自身网站的请求并修改。
    rekulas
    rekulas
    Apr 28, 2022
    25
    还可以把资源文件单独放个域名,相当于内部简陋版 cdn,通过 etag 等 header 进行缓存管控,你就可以随意控制缓存了,比如代码发布后自动更新清除缓存
    lk920724
    lk920724
    Apr 29, 2022
    26
    学习一下其他做法,mark~
    yuzo555
    yuzo555
    Apr 29, 2022
    27
    标准的做法是通过 Cache-Control: max-age=600 来控制浏览器缓存一个文件的时间,600 是秒数;
    或者不在乎服务器压力的话直接 Cache-Control: no-cache 不缓存;

    但是如果客户端比较多样化,有些垃圾浏览器很可能是只判断后缀不遵守这个规则的。
    最灵活的方式还是直接在网页代码里加 URL 参数 queryString ,例如 a.js?ver=202204290056 ,每次更新用 ver 记录版本号或者更新时间,这样浏览器就不会读旧缓存。

    上面说的 ETag 或者 Last-Modified ,不符合楼主这个场景,这俩是要 [等到浏览器认为缓存过期了] ,然后去服务器请求,服务端判断客户端请求头里的 If-None-Match 或者 If-Modified-Since ,如果服务器认为客户端的版本不需要更新,可以直接返回一个 304 Not Modified ,节省传输流量用的。
    ch2
    ch2
    Apr 29, 2022
    28
    每次更新后生成的 js 都用 hash 命名,只更改 index.html 引用的 js 文件名,这样就能够保证用户使用的 js 要么全是旧版的,要么全是新版的,你只要更新一个 index.html 就行了
    Zy143L
    Zy143L
    Apr 29, 2022 via Android
    29
    + hash 加版本号 这都是老生常谈的问题了
    mozhizhu
    mozhizhu
    Apr 29, 2022
    30
    没打开之前,就知道一定有 alert <_<
    dartabe
    dartabe
    Apr 29, 2022
    31
    Mark. 看来 no-cache 并不是什么好方案
    yunye
    yunye
    Apr 29, 2022
    32
    前端获取当前时间戳,然后拼接一下 xxx.js?ver=时间戳
    IvanLi127
    IvanLi127
    Apr 29, 2022 via Android
    33
    如果你打开 devtools 勾选了禁用缓存能正常工作,那么加 no-cache 是一个有效且改动很小的方案。如果能在 nginx 上改的话,几乎稳得一批
    superfatboy
    superfatboy
    Apr 29, 2022
    34
    修改一下 ,服务端 配置不就完事了,完全不缓存,内容部用的系统也没事
    ImmerTry
    ImmerTry
    Apr 29, 2022
    35
    @superfatboy 是像楼上那样 在 nginx 上做改动吗
    superfatboy
    superfatboy
    Apr 29, 2022
    36
    @ImmerTry 差不多,详细的配置,上网搜下就有
    unco020511
    unco020511
    Apr 29, 2022
    37
    后面加上版本号呀
    bzw875
    bzw875
    Apr 29, 2022
    38
    js 做不到,在 http 可以设置 Cache-Control 、ETag 、Expires 、Last-modified 。在前端构建工具( webpack 、rollup )给 js 和 css ,图片加上文件哈希前缀比如 uhu43824f.js
    PEAL
    PEAL
    Apr 29, 2022
    39
    @bzw875 曾经我以为这样子就完全可以了,直到遇到了一个国企的 APP 端网页,死缓存,只能在系统清除该 APP 缓存才能清除
    liyunyang
    liyunyang
    Apr 29, 2022
    40
    公司有一样的问题,up 有解决方案的时候 @一下我,233333
    liyunyang
    liyunyang
    Apr 29, 2022
    41
    之前听说 js 后面加版本号,再微信浏览器里面会被过滤?不知道这个说法是否正确
    Felldeadbird
    Felldeadbird
    Apr 29, 2022
    42
    楼主没说项目的页面是不是静态页。我假定你全是后端渲染。
    1. 不考虑带宽损耗,直接 xxx.js?time=随机值。
    2. xxx.js?v=全局版本号变量

    如果是静态页.
    1. 想办法定期更新静态页的代码。xxx.js?v=带上版本号

    如果是打包项目,就从打包源码上解决。每次打包就更新所有 js 的版本号。
    kangyan
    kangyan
    Apr 29, 2022
    43
    webpack 打包不是可以加 hash 后缀嘛,OP 的项目不能上 webpack 是吧
    davin
    davin
    Apr 29, 2022
    44
    强制缓存 vs 协商缓存了解一下
    dumbass
    dumbass
    Apr 29, 2022
    45
    @oneisall8955 #7 哈哈哈哈,看到标题我就想到这个
    zloong
    zloong
    Apr 29, 2022
    46
    如果是单页应用,打包后的资源文件都是带 hash 的,所以只要配置服务器不缓存 index.html 就可以了 https://www.jianshu.com/p/5e7d4030254a
    serge001
    serge001
    Apr 29, 2022❤️1
    47
    先说一下最佳的实践方案:
    将 html 和资源文件分开两个域名部署,html 文件 cache-control:no-cache ;每次访问让浏览器都去请求一次服务器;资源文件每次发布加 hash/版本号,设置强缓存:cache-control:max-age=60000 每次加载资源文件都使用本地缓存

    对于你的问题,很明显就是服务器返回的 cache-control 响应头有问题,无脑的解决方案就是设置 cache-control: no-cache ;
    unsized
    unsized
    Apr 29, 2022 via iPhone
    48
    @yuzo555 你说错了。no-cache 是忽略本地缓存时间,任然会带上 if-none-match 和 if-modified-since 请求头跟服务端协商。no-store 才是完全忽略本地缓存。
    serge001
    serge001
    Apr 29, 2022
    49
    @tyx1703 协商缓存有什么问题
    unsized
    unsized
    Apr 29, 2022 via iPhone
    50
    @serge001 服务端响应 304 的情况下还会采用之前的本地缓存。
    DICK23
    DICK23
    PRO
    Apr 29, 2022
    51
    内网项目,直接 cache-control: no-store 就完事了,再狠点就用打包工具生成 hash
    libook
    libook
    Apr 29, 2022
    52
    编程有两大难题,第一个是起名字,第二个就是缓存管理。

    把代码尽可能移到外部引用的文件里,主页 html 尽可能简单,仅用于引用加载其他文件,然后关闭针对主页 html 的任何缓存,确保每次都从服务器拉最新版本,其他文件加缓存。
    每次更新代码,发布的时候都修改其他文件名,比如加一个随机字符串,然后在 html 中引用的时候引用新的文件,这样浏览器加载主页 html 之后,发现需要加载的其他文件跟已经缓存的路径不一样,就重新去拉新文件加载了。

    这一套现在有很多前端打包工具可以自动化完成,比如 webpack ,你要是项目不适合引入打包工具自己写一个脚本处理一下也可以。
    onionKnight888
    onionKnight888
    Apr 29, 2022
    53
    ctrl+shift+R
    icanfork
    icanfork
    Apr 29, 2022
    54
    location / {
    root /usr/local/nginx/html;
    index index.html;

    if ($request_filename ~* ^.*?.(html|htm)$) {
    add_header Cache-Control "private, no-store, no-cache, must-revalidate, proxy-revalidate";
    }
    }
    jydeng
    jydeng
    Apr 29, 2022
    55
    html 禁止缓存 + js 文件名 hash
    ImmerTry
    ImmerTry
    Apr 29, 2022
    56
    @helee9199 OP 是部署到 tomcat 上的吧
    serge001
    serge001
    Apr 29, 2022
    57
    @tyx1703 返回 304 那就是服务端的缓存控制出问题了
    rekulas
    rekulas
    Apr 29, 2022
    58
    忽略我上面说的,header 确实没法更新缓存,还是只能加 url
    不过突然灵光一闪,如果不嫌麻烦,还可以试试 serviceworker ,相当于在前端搭建了个 CDN 。。
    lmshl
    lmshl
    Apr 29, 2022
    59
    你正在访问的这个网站,是这么解决的:
    <script src="/assets/ad64c164f9c6f240aa3940ff6ace27be7981f830-combo.js" defer=""></script>
    WGNNN
    WGNNN
    Apr 29, 2022
    60
    alert("清除缓存成功")
    helee9199
    helee9199
    OP
    Apr 29, 2022
    61
    @ImmerTry 对的 而且 还是 jsp
    iqoo
    iqoo
    Apr 29, 2022❤️1
    62
    最简单的办法,无需修改已有业务。

    新增一个脚本,定义哪些 URL 需强制更新,用 no-cache 模式去 fetch 即可:

    ```
    URL_LIST = [
    '/1.js',
    '/2.js',
    // ....
    ]

    URL_LIST.forEach(url => {
    fetch(url, {
    cache: 'no-cache',
    })
    })
    ```
    serge001
    serge001
    Apr 29, 2022
    63
    果然面试题问 http 缓存还是能考出来一些问题的
    RabbitDR
    RabbitDR
    Apr 29, 2022
    64
    现在的话,一种叫“revving”的技术用得比较多。
    https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching#%E6%94%B9%E8%BF%9B%E8%B5%84%E6%BA%90
    Huelse
    Huelse
    Apr 29, 2022
    65
    所有的链接末尾都加上`?t=${new Date().getTime()}`
    itechify
    itechify
    Apr 29, 2022
    66
    想起来了,以前写 thymeleaf 模板,可以这样,带上时间

    <script th:src="@{'/js/xxx.js?v='+${#httpServletRequest?.session?.lastAccessedTime}}"></script>

    jsp 应该也有差不多的语法吧
    OHyn
    OHyn
    Apr 29, 2022
    67
    一个办法是服务器配置下,所有静态资源请求全加上 Cache-control: no-store 。直接干掉缓存。

    js 文件可以在 url 中加随机 query 强行请求。但 html 文件是另一个问题----个人感觉不在响应头里面动手脚的话,html 文件的缓存无解哎,一般都得配一下,html 文件不缓存。
    fstar
    fstar
    Apr 29, 2022❤️1
    68
    HTTP 头字段只是标准,在什么时候缓存,什么时候不缓存。
    浏览器理论上会遵守,但有些细节可能不会遵守,或者会变化,比如 Chorme 80 版本后将 Cookie 的 SameSite 由原来的 None 改为了 Lax 。
    此外可能某个版本有实现上的 bug 。
    在技术群,有个群友说他的套壳 APP ,设置了 Cache-control: no-store 没效果,还是拿到的缓存内容。我觉得可能是 APP 套壳的浏览器有问题。

    所以,我想说的是,最好还是给文件名加哈希值,最稳妥。毕竟获取一个从来没访问过的资源,浏览器本地是不可能有缓存的。
    serge001
    serge001
    Apr 29, 2022
    69
    @fstar 设置了 Cache-control: no-store 没效果, 会不会是设置之前本地已经有了缓存,这样情况下就不会立刻生效 要等本地缓存过期才行
    iyaozhen
    iyaozhen
    Apr 29, 2022
    70
    话说回来面试还得问,https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching 能把这个吃透,真的不是应付面试,是真的有用
    xiangyuecn
    xiangyuecn
    Apr 29, 2022
    71
    楼上叫 url 加 hash 的,怎么想的,他这种老项目 一个 js 内容变了,几百个 html 要改代码,就问你怕不怕😂

    web 服务器 加 Cache-Control 响应头,目测是最简单的解。其他方案 至少要有一次大规模修改代码

    改用户端环境?叫装插件?比改代码难多了!
    InDom
    InDom
    Apr 29, 2022
    72
    其实 #62 楼已经给出解决方案了...
    duke807
    duke807
    Apr 29, 2022 via Android
    73
    看我這個 cdencrypt 源碼 https://www.v2ex.com/t/832302

    主 js 對比其它 js 和資源文件的 sha 值,不對的話強制重新拉取

    js 和資源文件的文件名不用加入版本信息,方便版本管理
    duke807
    duke807
    Apr 29, 2022 via Android
    74
    各文件 sha 值合成的列表用源碼目錄下的 tools 目錄下的腳本自動生成
    zyy314680012
    zyy314680012
    Apr 30, 2022 via Android
    75
    我们 20 年前的时候都是 src 后面加版本号
    haah
    haah
    Apr 30, 2022
    76
    正确的方法难道不是合理利用“缓存”么?
    litel
    litel
    Apr 30, 2022
    77
    index.html 加上 no-cache 就好
    当然是在 js 有哈希变动的情况下
    lizhien
    lizhien
    Apr 30, 2022
    78
    直接让他们用无痕不就完了
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   862 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 120ms · UTC 20:56 · PVG 04:56 · LAX 12:56 · JFK 15:56
    ♥ Do have faith in what you're doing.