V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
edis0n0
V2EX  ›  程序员

SPA 配置错误导致 index.html 被用户浏览器缓存了,不刷新页面就一直是旧版本,有办法在 SPA 请求的 API 请求的响应头中告诉浏览器需要清除全部页面的缓存吗? StackOverflow 找了很久,没有一个方案是可用的。

  •  
  •   edis0n0 · 89 天前 · 2865 次点击
    这是一个创建于 89 天前的主题,其中的信息可能已经有所发展或是发生改变。
    把 index.html 删了都没用,浏览器根本不会为这个网页发送请求。
    16 条回复    2022-11-12 10:42:30 +08:00
    yaphets666
        1
    yaphets666  
       89 天前
    service worker 的 cache? 这个以前看过一些,但是具体的技术细节要你自己去看
    winglight2016
        2
    winglight2016  
       89 天前
    入口被缓存了,这大概无解了。不过可以试试,nginx 设置索引页面为 index.htm
    bojackhorseman
        3
    bojackhorseman  
       89 天前 via iPhone
    找运维看配置下 nginx
    oott123
        4
    oott123  
       89 天前   ❤️ 3
    巧了,还真的有一个: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Clear-Site-Data
    但要不是同一个子域名的话可能也不管用
    sujin190
        5
    sujin190  
       89 天前
    如果是入口页并不会完全缓存不发请求吧
    如果你是配置了 manifest 指明首页可以离线使用,那么肯定会请求 manifest 信息啊,你通过新的 manifest 返回首页过期信息就行了吧
    如果 service worker ,那么启动 service worker 的 sw.js 会请求,再里边写删缓存的代码就行吧,所以你这个不能清是个啥情况。。
    edis0n0
        6
    edis0n0  
    OP
       89 天前
    @sujin190 #5 没有 service worker ,入口页还是被缓存了,浏览器 network 里所有访问过的路由都会显示 cache from disk ( IIS 默认配置+ASP.NET Core with Angular 的官方模板 就存在这个问题,100%复现)
    ragnaroks
        7
    ragnaroks  
       89 天前
    试下 #4 的方法?说实话我做网站开放那么长时间都没遇到这种问题,但是你描述的这个问题我一时间和你一样完全没有头绪。我现在想到的是永远不要让 MIME text/html 的缓存时间大于域名 TTL 。
    edis0n0
        8
    edis0n0  
    OP
       89 天前
    @ragnaroks #7 目前就是做了一个 interceptor 在新版本所有请求加上前端程序版本号,后端发现没传或低于做的版本号就在请求头加上 4 楼的内容并返回 400 错误要求用户刷新。
    shunia
        9
    shunia  
       89 天前
    接口推送一个前端能处理的错误号,能处理的意思是最好能让用户看到错了。这样用户会想办法处理,或者反馈客服,这个过程用户就有机会清理掉缓存了。
    加版本号没啥用啊,SPA 的话只要不缓存 index.html 就行了。
    edis0n0
        10
    edis0n0  
    OP
       89 天前
    @shunia #9 没传版本号的就是存在这个 index.html 被缓存问题的用户,这些用户浏览器上的版本无法被更新,只能通过这种方式标记出来要求用户刷新解决问题。
    edis0n0
        11
    edis0n0  
    OP
       89 天前
    @edis0n0 #8 做的=>最低 字打错了
    wu67
        12
    wu67  
       89 天前
    一个我曾经用过的思路:
    你们的后台管理, 做一个客户端版本号的表单页.
    让接口每次返回都把这个版本号带到返回数据里面, 这个版本号可以缓存, 不用每次读数据库, 但务必保证后台管理页更新时, 这个缓存会刷新.
    这时你在前端项目里也用上版本号, 每次发版都更新, 在请求响应拦截里面操作你应该会了吧, 接口版本更高就刷新页面. 你也可以做一个心跳轮询, 如果项目里面本身就有 websocket 就更容易了, 直接推送.
    90xchun
        13
    90xchun  
       88 天前 via Android
    可以参考一下 nextjs 的实现逻辑,nextjs 每次 csr 的时候数据请求会 _next/ 加一个随机的字符,nextjs 每次 build 完后都会不一样,所以有新版本时候用户在页面点击下一个页面时,csr 的接口就会 404 ,然后就会强制重新加载整个页面,以保证用户在接下来的操作都是在最新的版本上进行的
    LittleDust
        14
    LittleDust  
       88 天前 via iPhone
    302 重定向到一个新的页面的
    shanghai1998
        15
    shanghai1998  
       88 天前
    我们后端会维护一个版本号,前端本地有版本号变量,首页请求下最新版本号,和本地不一致,直接 index.html?t=new Date().getTime()
    简单好使
    IvanLi127
        16
    IvanLi127  
       88 天前 via Android
    已经不请求了,要么让用户手动强刷页面或者换浏览器访问,要么找个还能向服务器请求的 js 文件或者做 xss 注入并执行的代码,把浏览器跳转到新页面去,保业务能用先。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   实用小工具   ·   1250 人在线   最高记录 5556   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 42ms · UTC 20:26 · PVG 04:26 · LAX 12:26 · JFK 15:26
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.