You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter Web应用在Chrome中二次加载失败问题求助

Flutter Web应用Chrome二次加载失败问题排查与解决

背景

我在DigitalOcean Droplet上部署了一个Flutter Web应用。

web/index.html 代码

<!DOCTYPE html>
<html>
<head>
  <base href="/">

  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="Webapp for Occulead">

  <!-- iOS meta tags & icons -->
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="apple-mobile-web-app-title" content="Occulead">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

  <!-- Favicon -->
  <link rel="icon" type="image/png" href="favicon.png"/>

  <title>Occulead</title>
  <link rel="manifest" href="manifest.json">
</head>
<body>
<script src="flutter_bootstrap.js" async></script>
<!--<script>-->
<!--  // Register service worker-->
<!--  if ('serviceWorker' in navigator) {-->
<!--    window.addEventListener('load', function() {-->
<!--      navigator.serviceWorker.register('/service-worker.js').then(function(registration) {-->
<!--        console.log('ServiceWorker registration successful with scope: ', registration.scope);-->
<!--      }, function(err) {-->
<!--        console.log('ServiceWorker registration failed: ', err);-->
<!--      });-->
<!--    });-->
<!--  }-->
<!--</script>-->
</body>
</html>

Nginx 配置

server {
    listen 80;
    server_name my_IP;

    location / {
        root /var/www/occulead_flutter/web;
        index index.html;
        try_files $uri $uri/ /index.html;

        # Disable caching
        add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
        add_header Pragma "no-cache";
        add_header Expires 0;

        types {
            text/html html;
            text/css css;
            application/javascript js;
        }
    }
}

问题描述

该Web应用在Safari中运行正常,但Chrome中首次加载正常,关闭标签页后再次打开无法加载;清除浏览器缓存和历史记录后可正常加载一次,再次加载又失败。

已尝试的解决方法

  • 禁用了Flutter应用的Service Worker(见index.html注释代码)
  • 通过Nginx配置全局禁用缓存
  • 查看Nginx访问日志,确认仅首次加载有请求日志,二次加载时浏览器未向服务器发起请求
  • 在Chrome开发者工具中勾选"Disable cache"后重试,问题依旧
  • 使用最新稳定版Flutter 3.22.1构建应用

问题根源与解决方案

问题根源

  1. 残留Service Worker拦截请求:Chrome对Service Worker的缓存机制严格,即使注释了注册代码,之前已注册的Service Worker仍会驻留在浏览器中,拦截二次加载请求,导致从本地缓存读取失败资源。
  2. Nginx缓存策略不合理:全局禁用缓存的配置未覆盖所有场景,且静态资源的缓存策略缺失,反而可能导致浏览器异常处理缓存。

解决步骤

1. 彻底清除Chrome中残留的Service Worker与缓存

  • 打开Chrome开发者工具(F12),切换到Application标签页
  • 左侧菜单找到Service Workers,勾选"Update on reload",点击所有相关Service Worker的"Unregister"按钮
  • 在左侧Storage菜单中,点击"Clear site data",清除所有缓存数据

2. 优化Nginx缓存配置

修改Nginx配置,针对不同资源设置精准的缓存策略:

server {
    listen 80;
    server_name my_IP;

    root /var/www/occulead_flutter/web;
    index index.html;

    location / {
        try_files $uri $uri/ /index.html;
        
        # HTML文件强制不缓存,确保每次请求都获取最新内容
        if ($request_uri ~* \.html$) {
            add_header Cache-Control "no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0";
            add_header Pragma "no-cache";
            add_header Expires 0;
        }
        
        # 静态资源设置长期缓存,Flutter构建会自动为资源添加哈希指纹,更新时自动失效
        location ~* \.(css|js|png|jpg|jpeg|svg|ico|json)$ {
            add_header Cache-Control "public, max-age=31536000, immutable";
        }
    }
}
  • 原配置中的types块可删除,Nginx默认已包含这些MIME类型映射
  • 修改后执行sudo nginx -s reload生效配置

3. 重新构建Flutter Web应用

  • 执行flutter clean清理旧构建文件
  • 重新构建生产版本:flutter build web --release
  • 确认构建后的web目录中service-worker.js已被删除(若仍存在,可手动删除)

4. 验证manifest.json配置

检查manifest.json中的start_url是否为"/",display字段设置为"standalone"或"browser",避免PWA模式下的缓存异常。

内容的提问来源于stack exchange,提问作者Arjun Issar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:20:10