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

Flutter Web应用更新后需二次刷新才生效,求缓存清除方案

Flutter Web 新版本缓存问题解决方案

你遇到的是Flutter Web常见的静态资源缓存问题——浏览器或Service Worker会缓存旧版本的编译文件(如main.dart.js、静态资源),但package_info_plus读取的是打包时嵌入的版本元数据(不受缓存影响),所以会出现版本号正确但页面内容仍是旧版的情况。以下是几种实用的解决方法:

1. 优化服务器缓存策略

Flutter Web打包时会给编译后的核心文件(如main.xxx.dart.js)添加哈希后缀,新版本文件名会变化,浏览器会自动请求新文件。关键要确保index.html不被长期缓存:

  • 给index.html设置严格的缓存控制头:Cache-Control: no-cache, no-store, must-revalidate,让浏览器每次都向服务器请求最新的index.html,从而加载新版本的哈希文件名资源。
  • 对带哈希后缀的静态资源设置较长缓存时间(如Cache-Control: max-age=31536000),提升后续加载速度。

2. 主动检测Service Worker更新

Flutter Web默认会注册Service Worker来缓存资源,新版本发布后需要触发Service Worker更新:
在main.dart中添加检测逻辑,启动时检查Service Worker状态:

import 'dart:html' as html;
import 'package:flutter/material.dart';

final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();

void main() {
  runApp(MyApp(navigatorKey: navigatorKey));
  // 检测Service Worker更新
  if (html.window.navigator.serviceWorker != null) {
    html.window.navigator.serviceWorker!.register('/flutter_service_worker.js')
        .then((registration) {
      registration.update().then((_) {
        if (registration.waiting != null) {
          // 提示用户刷新以应用新版本
          showUpdateDialog();
        }
      });
    });
  }
}

void showUpdateDialog() {
  WidgetsBinding.instance.addPostFrameCallback((_) {
    showDialog(
      context: navigatorKey.currentContext!,
      builder: (context) => AlertDialog(
        title: const Text('发现新版本'),
        content: const Text('请刷新页面以加载最新内容'),
        actions: [
          TextButton(
            onPressed: () => html.window.location.reload(),
            child: const Text('立即刷新'),
          ),
        ],
      ),
    );
  });
}

class MyApp extends StatelessWidget {
  final GlobalKey<NavigatorState> navigatorKey;
  const MyApp({super.key, required this.navigatorKey});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: navigatorKey,
      home: const Scaffold(body: Center(child: Text('Flutter Web App'))),
    );
  }
}

3. 版本对比触发刷新提示

利用package_info_plus能获取正确版本的特性,和后端维护的最新版本做对比,不一致时提示用户刷新:

import 'package:package_info_plus/package_info_plus.dart';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';

void checkForUpdate() async {
  PackageInfo packageInfo = await PackageInfo.fromPackageInfo();
  String currentVersion = packageInfo.version;
  
  // 调用后端接口获取最新版本号
  final response = await http.get(Uri.parse('/api/latest-version'));
  if (response.statusCode == 200) {
    String latestVersion = response.body.trim();
    if (currentVersion != latestVersion) {
      // 提示用户刷新(可复用上面的showUpdateDialog方法)
      showUpdateDialog();
    }
  }
}

在应用启动时调用checkForUpdate()即可。

4. 手动添加版本参数(备选方案)

如果无法修改服务器配置,可在打包时给静态资源引用添加版本参数:
修改web/index.html中main.dart.js的引用:

<script src="main.dart.js?v=1.0.1"></script>

每次发版时更新v的值,强制浏览器请求新资源。不过Flutter默认的哈希命名机制已经能解决这个问题,此方案仅用于特殊场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 12:52:53