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

Flutter Web更新index.html消除弃用警告后页面空白问题求助

解决Flutter Web更新index.html消除弃用警告后页面空白问题

问题背景

我尝试更新Flutter Web的index.html以消除以下弃用警告,但开发模式运行应用时页面显示空白:

Warning: In index.html:39: Local variable for "serviceWorkerVersion" is deprecated. Use "{{flutter_service_worker_version}}" template token instead.
Warning: In index.html:49: "FlutterLoader.loadEntrypoint" is deprecated. Use "FlutterLoader.load" instead.

原始index.html代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="blah">

  <!-- 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="notmuch">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

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

  <title>test</title>
  <link rel="manifest" href="manifest.json">

  <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/10.4.0/firebase-app-compat.min.js"></script>

  <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/10.4.0/firebase-messaging-compat.min.js"></script>

  <script>const firebaseConfig = {
    apiKey: "secret",
    authDomain: "secret",
    projectId: "secret",
    storageBucket: "secret",
    messagingSenderId: "secret",
    appId: "secret",
    measurementId: ""
  };

firebase.initializeApp(firebaseConfig);
</script>

  <script>
    // The value below is injected by flutter build, do not touch.
    const serviceWorkerVersion = null;
  </script>
  <!-- This script adds the flutter initialization JS code -->
  <script src="flutter.js" defer></script>
</head>
<body>
  <script>
    window.addEventListener('load', function(ev) {

      // Download main.dart.js
      _flutter.loader.loadEntrypoint({
        serviceWorker: {
          serviceWorkerVersion: serviceWorkerVersion,
        },
          onEntrypointLoaded: function(engineInitializer) {
          
            navigator.serviceWorker.register("firebase-messaging-sw.js");

            var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
                      
            engineInitializer.initializeEngine().then(function(appRunner) {          
              appRunner.runApp();
            });
        }
      });
    })
  </script>
</body>
</html>

ChatGPT修改后的代码(存在问题)

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="blah">

  <!-- 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="notmuch">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

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

  <title>test</title>
  <link rel="manifest" href="manifest.json">

  <!-- Firebase SDK -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/10.4.0/firebase-app-compat.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/10.4.0/firebase-messaging-compat.min.js"></script>

  <!-- Firebase Configuration -->
  <script>
    const firebaseConfig = {
      apiKey: "secret",
      authDomain: "secret",
      projectId: "secret",
      storageBucket: "secret",
      messagingSenderId: "secret",
      appId: "secret",
      measurementId: ""
    };
    firebase.initializeApp(firebaseConfig);
  </script>

  <!-- Service Worker Version -->
  <script>
    // Use the template token provided by Flutter.
    const serviceWorkerVersion = "{{flutter_service_worker_version}}";
  </script>

  <!-- Flutter Initialization Script -->
  <script src="flutter.js" defer></script>
</head>
<body>
  <script>
    window.addEventListener('load', function(ev) {
      // Using the updated FlutterLoader.load method.
      _flutter.loader.load({
        serviceWorker: {
          serviceWorkerVersion: serviceWorkerVersion,
        },
        onEngineCreated: function(engine) {
          // Register Firebase service worker here, before running the app.
          navigator.serviceWorker.register("firebase-messaging-sw.js")
            .then(function(registration) {
              console.log('Firebase service worker registered with scope:', registration.scope);
            }).catch(function(error) {
              console.error('Firebase service worker registration failed:', error);
            });

          // Continue with Flutter app initialization.
          engine.run();
        }
      });
    });
  </script>
</body>
</html>

问题分析

ChatGPT的修改存在两处核心问题,导致开发模式页面空白:

  1. Service Worker版本处理不当:开发模式下Flutter不会替换{{flutter_service_worker_version}}模板token,导致serviceWorkerVersion为无效字符串,干扰Flutter的service worker加载逻辑。
  2. 错误使用回调函数:onEngineCreated并非_flutter.loader.load的标准回调参数,Flutter新API仍需通过onEntrypointLoaded完成引擎初始化和应用启动流程。

正确修复后的index.html代码

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta content="IE=Edge" http-equiv="X-UA-Compatible">
  <meta name="description" content="blah">

  <!-- 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="notmuch">
  <link rel="apple-touch-icon" href="icons/Icon-192.png">

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

  <title>test</title>
  <link rel="manifest" href="manifest.json">

  <!-- Firebase SDK -->
  <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/10.4.0/firebase-app-compat.min.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/firebase/10.4.0/firebase-messaging-compat.min.js"></script>

  <!-- Firebase Configuration -->
  <script>
    const firebaseConfig = {
      apiKey: "secret",
      authDomain: "secret",
      projectId: "secret",
      storageBucket: "secret",
      messagingSenderId: "secret",
      appId: "secret",
      measurementId: ""
    };
    firebase.initializeApp(firebaseConfig);
  </script>

  <!-- Service Worker Version - 兼容开发/生产环境 -->
  <script>
    let serviceWorkerVersion = null;
    // 生产环境下Flutter会自动替换模板token,开发环境保持null
    if ("{{flutter_service_worker_version}}" !== "{{flutter_service_worker_version}}") {
      serviceWorkerVersion = "{{flutter_service_worker_version}}";
    }
  </script>

  <!-- Flutter Initialization Script -->
  <script src="flutter.js" defer></script>
</head>
<body>
  <script>
    window.addEventListener('load', function(ev) {
      // 初始化参数:开发环境不配置service worker
      const loadOptions = {};
      if (serviceWorkerVersion !== null) {
        loadOptions.serviceWorker = {
          serviceWorkerVersion: serviceWorkerVersion,
        };
      }

      _flutter.loader.load({
        ...loadOptions,
        onEntrypointLoaded: async function(engineInitializer) {
          // 注册Firebase消息推送Service Worker
          try {
            const registration = await navigator.serviceWorker.register("firebase-messaging-sw.js");
            console.log('Firebase service worker registered:', registration.scope);
          } catch (error) {
            console.error('Firebase service worker注册失败:', error);
          }

          // 初始化Flutter引擎并启动应用
          const appRunner = await engineInitializer.initializeEngine();
          appRunner.runApp();
        }
      });
    });
  </script>
</body>
</html>

关键修改说明

  1. 兼容开发/生产的Service Worker版本:通过判断模板token是否被替换,自动切换开发/生产模式的service worker配置,避免开发模式下无效值导致的加载失败。
  2. 标准API回调使用:沿用onEntrypointLoaded回调,遵循Flutter官方新API的初始化流程,确保引擎正确初始化和应用启动。
  3. Service Worker注册优化:使用异步语法简化Firebase service worker的注册逻辑,同时确保不会阻塞Flutter应用的初始化。
  4. 开发模式跳过Service Worker:开发模式下不传入service worker配置,符合Flutter Web默认行为,避免冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 23:17:03