【问题标题】:Firebase Hosting Flutter Web App not clearing Cache of first deployFirebase 托管 Flutter Web 应用程序未清除首次部署的缓存
【发布时间】:2020-08-07 18:34:27
【问题描述】:

我们构建了一个 Flutter Web 应用并通过 Firebase 托管进行部署。不幸的是,我们在初始部署中没有配置任何缓存设置。

现在我们部署了更新版本的网站,但人们仍然会从第一次部署中看到旧网站。到目前为止我们尝试了什么:

添加版本号到我们的 index.html:

<"script src="main.dart.js?version=1" type="application/javascript"></script>

在 index.html 的标头中添加元数据:

  <meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate" />
  <meta http-equiv="Pragma" content="no-cache" />
  <meta http-equiv="Expires" content="0" />

在我们的 firebase.json 中,我们添加了以下标头:

"headers": [
      {
        "source": "**",
        "headers": [
          {
            "key": "Cache-Control",
            "value": "max-age=10"
          }
        ]
      }
    ]

所有这些尝试都没有成功。我们认为问题在于较新版本的文件中没有这些条目。我们如何强制它更新到我们的最新版本?如果有帮助,我们甚至会考虑开设一个新的 firebase 项目。

非常感谢您的帮助!

【问题讨论】:

  • 你能成功做到这一点吗?

标签: firebase flutter web caching hosting


【解决方案1】:

如果最近创建的项目具有 serviceWorkerVersion 元素,它会在编译时更新版本,我看到 Flutter 现在默认在 index.html 中包含此脚本:

<script>
var serviceWorkerVersion = null;
var scriptLoaded = false;
function loadMainDartJs() {
  if (scriptLoaded) {
    return;
  }
  scriptLoaded = true;
  var scriptTag = document.createElement('script');
  scriptTag.src = 'main.dart.js';
  scriptTag.type = 'application/javascript';
  document.body.append(scriptTag);
}

if ('serviceWorker' in navigator) {
  // Service workers are supported. Use them.
  window.addEventListener('load', function () {
    // Wait for registration to finish before dropping the <script> tag.
    // Otherwise, the browser will load the script multiple times,
    // potentially different versions.
    var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
    navigator.serviceWorker.register(serviceWorkerUrl)
      .then((reg) => {
        function waitForActivation(serviceWorker) {
          serviceWorker.addEventListener('statechange', () => {
            if (serviceWorker.state == 'activated') {
              console.log('Installed new service worker.');
              loadMainDartJs();
            }
          });
        }
        if (!reg.active && (reg.installing || reg.waiting)) {
          // No active web worker and we have installed or are installing
          // one for the first time. Simply wait for it to activate.
          waitForActivation(reg.installing ?? reg.waiting);
        } else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
          // When the app updates the serviceWorkerVersion changes, so we
          // need to ask the service worker to update.
          console.log('New service worker available.');
          reg.update();
          waitForActivation(reg.installing);
        } else {
          // Existing service worker is still good.
          console.log('Loading app from service worker.');
          loadMainDartJs();
        }
      });

    // If service worker doesn't succeed in a reasonable amount of time,
    // fallback to plaint <script> tag.
    setTimeout(() => {
      if (!scriptLoaded) {
        console.warn(
          'Failed to load app from service worker. Falling back to plain <script> tag.',
        );
        loadMainDartJs();
      }
    }, 4000);
  });
} else {
  // Service workers not supported. Just drop the <script> tag.
  loadMainDartJs();
}

【讨论】:

    【解决方案2】:

    试试这个:

    在你的 Flutter 应用中,在 web 文件夹中的 index.html 中,在 src="main.dart.js 之后添加一个版本号

    所以你的新行将如下所示:

    &lt;script src="main.dart.js?version=1" type="application/javascript"&gt;&lt;/script&gt;

    然后在每次构建之前将版本号增加到 2 等。

    2021 年 6 月更新:在 index.html 中添加这一行作为正文中的最后一个脚本

    【讨论】:

    • 谢谢,我实际上并没有在文档中看到,只是假设新部署的正在替换来自终端的消息为 finalizing version...version finalizedreleasing new version...、@987654326 之前的那个@.. 刚才我意识到“版本..”哈哈。非常感谢
    • 这对我不起作用。在更新之前仍然需要一两次刷新(没有区别)。
    【解决方案3】:

    如果你不想使用 server worker 缓存,你可以提供--pwa-strategy=none。否则,应用程序将在新版本下载并重新访问页面后更新。

    示例:

    flutter build web --release --pwa-strategy=none

    它将生成一个没有主体的服务工作者。这对于本地测试或在不需要 Service Worker 缓存功能的情况下很有用

    默认设置为offline-first:尝试快速缓存应用程序外壳,然后在加载所有后续资产时延迟缓存。在对资产进行网络请求时,将首选离线缓存。

    参考:

    【讨论】:

    • 如果在此之前我已经正常构建 web,并且想要实现这个 -pwa-strategy=none,我是否必须先清除缓存才能使其工作?或者它会立即生效
    • @ali 你可以先运行flutter clean
    • 除此之外,每次我想部署新版本时是否需要更改内部版本号?
    • 不一定
    猜你喜欢
    • 1970-01-01
    • 2021-03-28
    • 2018-05-07
    • 2021-05-09
    • 2021-02-15
    • 2023-02-21
    • 1970-01-01
    • 2021-07-23
    • 2022-01-14
    相关资源
    最近更新 更多