V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
2Nfree
V2EX  ›  程序员

大佬们关于这种前端容器滚动更新的问题有什么解决方案吗?

  •  
  •   2Nfree ·
    2Nfree · 3 天前 · 2012 次点击

    服务是内部服务,没有 CDN, 前端容器用 K8S 托管 现在发现一个问题: 前端滚动发布后,用户侧没关闭旧页面,还是指向之前的 js ,就会报错 Failed to loadmodule script: Expected JavaScriptmodule script but the server responded with a MIME type of "text/htmi".Strict MIME type checking is enforcedfor module scripts per HTML spec.

    现在想的解决办法就是更新后通知用户刷新,还有什么其他的方案吗?

    32 条回复    2025-04-04 13:52:48 +08:00
    julyclyde
        1
    julyclyde  
       3 天前
    别用容器
    你需要的是一个累积的存储装置,而不是可替换的存储装置
    zzhirong
        2
    zzhirong  
       3 天前
    出现这个问题的原因是,更新后,旧版本的 js 文件不存在了,然后,旧的页面链接还是指向旧的 js 文件,获取的时候,返回了 404.html (或其他),你这种情况可能是由于使用文件名来做版本控制(同一 js 文件不同版本不同的文件名),我能想到的方法是,固定 js 链接地址,再由后端来决定返回什么版本的 js ,或使用 HTTP Etag 头来做版本控制。
    learnshare
        3
    learnshare  
       3 天前
    1. 保留原有资源,包括静态文件和 API
    2. 更新和上线新版本
    3. 通知用户有更新,可以选择刷新或跳过

    PWA 应用里比较常见
    https://vite-pwa-org-zh.netlify.app/guide/prompt-for-update
    foolishcrab
        4
    foolishcrab  
       3 天前 via iPhone
    内部服务就让用户刷新一下,别折腾
    对客的你研究下静态资源发布吧,说复杂也挺复杂的一套东西
    2Nfree
        5
    2Nfree  
    OP
       3 天前
    @foolishcrab #4 嗯,现在想的就是让用户刷新,对客我们用的是 SSR 暂时没有这种问题
    2Nfree
        6
    2Nfree  
    OP
       3 天前
    @julyclyde #1 架构这一块估计我们不太会去折腾了
    2Nfree
        7
    2Nfree  
    OP
       3 天前
    @julyclyde
    @zzhirong
    @learnshare
    @foolishcrab
    感谢各位大佬
    eudore
        8
    eudore  
       3 天前
    为什么页面在加载之后还会加载 js ?不应该首次加载后加载所有 js 吗? 在更新瞬间访问导致版本不一样可以忽略,可以让 404 返回一段 js 去刷新页面。
    hahasong
        9
    hahasong  
       3 天前
    前端请求带上应用版本号,后端发现版本过低报错前端弹窗要求刷新
    superrichman
        10
    superrichman  
       3 天前
    window.setTimeout(function() {window.location.reload();}, 3600*1000);
    shunia
        11
    shunia  
       3 天前
    加一个针对这个异常的错误捕获,在捕获后弹窗提示用户刷新。
    zhangkai1024
        12
    zhangkai1024  
       3 天前
    我们在路由中捕获错误,根据错误的 error message 的某些关键特征命中有新的版本,并给出一个关不掉的 dialog 提示手动刷新
    9ki
        13
    9ki  
       3 天前
    目前我们是弹窗,如果发现有更新则强制弹窗提示告知用户,用户只能刷新

    我了解到比较完美的方式是蓝绿发布,但是我们服务器资源有限一直没尝试过

    有些网站例如:perplexity 只要检测到更新立马刷新网页
    xiaofeixiang
        14
    xiaofeixiang  
       3 天前
    两个解决方法:1 是静态文件传到静态资源服务器上,每次更新打包不删除上次的文件; 2 是每次打包生成一个版本号,然后页面轮训去查询是否版本更新,提醒用户刷新页面,这个有现成的插件,也可以自己手撸一个,不难
    bestie
        15
    bestie  
       3 天前
    @eudore 有个技术叫 lazyload ,访问到对应的路由才会加载 js
    guanzhangzhang
        17
    guanzhangzhang  
       3 天前
    小程序不就是版本不对让强制刷新的吗,看看类似原理?
    momocraft
        18
    momocraft  
       3 天前
    让用户刷新页面其实问题更少,你也不知道用户浏览器一直跑旧代码会产生什么问题
    YasinChan
        19
    YasinChan  
       3 天前
    使用协商缓存缓存
    ZZITE
        20
    ZZITE  
       3 天前
    一个是你参考的那样,对比版本进行主动的刷新提示。另外一般还需要再路由中或者全局对异常进行捕获,避免 lazyload 的部分在旧页面直接加载,导致程序崩溃。
    其实还有一种无感刷新的方式,但你这个场景考虑上面两种场景就可以了。
    shenyuzhi
        21
    shenyuzhi  
       3 天前
    index.html 文件 每次更新的时候覆盖
    js 和 css 文件,打包的时候生成 hash ,也就是生成这种文件名 my-module-1.4494a73d5ba8bad5.js
    保留以前的 js 和 css 文件
    Ghrhrrv146
        22
    Ghrhrrv146  
       3 天前
    碰到过这个问题,我的解决方案是捕获全局路由错误,如果错误为”Failed to loadmodule script: Expected JavaScriptmodule...“,自动刷新后,跳转至用户目标地址。
    molvqingtai
        23
    molvqingtai  
       3 天前
    使用 SSE 推送事件,强制刷新
    2Nfree
        24
    2Nfree  
    OP
       3 天前
    @ZZITE #20 了解了,感谢大佬
    Ghrhrrv146
        25
    Ghrhrrv146  
       3 天前
    @Ghrhrrv146 自动刷新后,跳转至用户目标地址 -> 自动刷新并跳转至用户目标地址
    2Nfree
        26
    2Nfree  
    OP
       3 天前
    @Ghrhrrv146 #25 但是我感觉这种方式不能错误保证一定是因为 JS 更新导致的吧,万一有其他的问题导致了相同的报错是不是就会反复刷新
    2Nfree
        27
    2Nfree  
    OP
       3 天前
    @2Nfree #26 现在我们的临时解决办法就是告诉用户更新了让他们自己刷新了,虽然感觉有点怪怪的,但是也还好
    rubbishmod
        28
    rubbishmod  
       3 天前
    无感自动刷新应该也只能通过 js 轮训请求 version 对比吧?评论区说的通过协商缓存的方案,nginx 只能命中某个 index.**hash**.js 重定向到 404 吧,所以没办法做到浏览器层面的刷新
    wu00
        29
    wu00  
       3 天前
    你这个问题是 index.html 缓存了,容器/滚动更新不背这个锅
    按道理来说你用户侧没关闭页面,他加载的是本地磁盘的 js 缓存,不会从服务器重新下载 js ,就算你设置了不缓存每次从服务器获取最新 js ,那为什么你的 html 不获取最新的呢,html 获取了最新的就不会去价值旧的 js 文件
    gausszhou
        30
    gausszhou  
       2 天前 via Android
    js css 加哈希,index.html 开协商缓存就可以了
    julyclyde
        31
    julyclyde  
       2 天前   ❤️ 1
    @2Nfree 先选了错误的方案,然后“架构这一块我们不去折腾了”
    那你就忍着吧
    pursuer
        32
    pursuer  
       2 天前
    现在前端都直接发布 es module 了吗?感觉 es module 还是灵活性比较差
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1052 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 23:27 · PVG 07:27 · LAX 16:27 · JFK 19:27
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.