【问题标题】:How do I cache other routes for offline browsing?如何缓存其他路线以供离线浏览?
【发布时间】:2023-03-09 18:30:30
【问题描述】:

我正在设置一个支持离线浏览的 Progressive Web App。

我已经为我的主要路由('domainsample.com/')设置了离线浏览,即使离线它也会响应 200。

但是当我导航到其他路线 ('domainsample.com/about') 时,我收到 No Internet Page 错误。

这是我在 Heroku 中部署的示例 URL:https://pwa-hehe.herokuapp.com

我使用 Vue CLI 3 设置项目并使用 Node.js 和 Express.js 在服务器中运行我的 dist 文件夹。

// server.js
const express = require('express')
const path = require('path')
const history = require('connect-history-api-fallback')

const app = express()

const staticFileMiddleware = express.static(path.join(__dirname + '/dist'))

app.use(staticFileMiddleware)

app.use(history({
    disableDotRule: true,
    verbose: true
}))

app.use(staticFileMiddleware)

app.get('/', function (req, res) {
    res.render(path.join(__dirname + '/dist/'))
})

var server = app.listen(process.env.PORT || 3000, function () {
    var port = server.address().port
    console.log("App now running on port", port)
})
// manifest.json
{
  "name": "pwa-offline",
  "short_name": "pwa-offline",
  "icons": [
    {
      "src": "./img/icons/android-chrome-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "./img/icons/android-chrome-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "start_url": "./index.html",
  "display": "standalone",
  "background_color": "#000000",
  "theme_color": "#4DBA87"
}

// service-worker.js

/**
 * Welcome to your Workbox-powered service worker!
 *
 * You'll need to register this file in your web app and you should
 * disable HTTP caching for this file too.
 * 
 *
 * The rest of the code is auto-generated. Please don't update this file
 * directly; instead, make changes to your Workbox build configuration
 * and re-run your build process.
 * 
 */

importScripts("https://storage.googleapis.com/workbox-cdn/releases/3.6.3/workbox-sw.js");

importScripts(
  "/precache-manifest.d3f1ce5d8331bddc555348f44cfba9d8.js"
);

workbox.core.setCacheNameDetails({prefix: "pwa-offline"});

/**
 * The workboxSW.precacheAndRoute() method efficiently caches and responds to
 * requests for URLs in the manifest.
 * 
 */
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

【问题讨论】:

  • 你在哪里定义的离线策略?我只看到你的网络清单,但没有看到 Service Worker 的代码。
  • 嗨,编辑了这个问题,我只使用 Vue CLI 3 自动生成的 service-worker.js,我相信我应该自己做?
  • 请问是否有任何答案有效,或者您是否找到了解决方案?

标签: vue.js vue-router progressive-web-apps offline-caching vue-cli-3


【解决方案1】:

问题在于您的 Service Worker 不知道要缓存哪些资产。 self.__precacheManifest 的值是多少? (可能是网络清单文件)。

您需要配置工作箱以便为precacheAndRoute 方法提供一些资产,因为这将指示服务工作者缓存哪些文件以及何时缓存。比如:

workbox.precaching.precacheAndRoute([
  '/styles/example.ac29.css',
  '/app/offlinePage.js',
  '/app/offlinePage.html',
  // ... other entries ...
]);

默认情况下,Service Worker 不知道要缓存哪些资产或 HTTP 响应,因此我们必须根据自己的要求定义和实现缓存策略。

我写了一篇关于service workers and the available caching strategies 的文章。如果您想加深主题,请查看它。

【讨论】:

  • 嗨,我会看看那篇文章,我相信在我将它集成到 vue.js 之前,我还需要对 workbox 和 service worker 进行更多研究,谢谢!
  • 如果答案帮助您继续或回答了您的问题,您应该将其标记为已解决。如果您从中学到了一些东西,最终 +1。
【解决方案2】:

对于同时使用 vue/cli-pligin-pwa 和 vue-cli 3 的任何人,我已经解决了这个问题。

vue/cli-pligin-pwa 在缓存您的 js 文件以供您的 Web 应用程序离线使用方面发挥作用。

但由于您使用的是单页应用程序,因此您必须设置某种回退。

页面例如(sample.com/about)的请求将是一个导航请求,它将为/index.html的缓存页面提供服务

来源https://developers.google.com/web/tools/workbox/modules/workbox-routing#how_to_register_a_navigation_route

所以我所做的是,我通过在我的 vue.config.js 文件

// vue.config.js

module.exports = {
    pwa: {
        // configure the workbox plugin
        workboxPluginMode: 'InjectManifest',
        workboxOptions: {
            swSrc: 'public/service-worker.js'
        }
    }
}

现在,在您的公共文件夹目录中创建一个 service-worker.js,并写下从 vue/cli-pligin-pwa 生成的代码行并添加以下行: workbox.routing.registerNavigationRoute('/index.html');

//service-worker.js

self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

workbox.routing.registerNavigationRoute('/index.html');

// install new service worker when ok, then reload page.
self.addEventListener("message", msg => {
    if (msg.data.action == 'skipWaiting') {
        self.skipWaiting()
    }
})

【讨论】:

    【解决方案3】:

    有一个更简单的解决方案,不涉及使用InjectManifest

    只需将此添加到您的 vue.config.js 文件中:

    pwa: {
      workboxOptions: {
        navigateFallback: 'index.html'
      }
    }
    

    它会自动将必要的代码添加到你的 service worker:

    workbox.routing.registerNavigationRoute(workbox.precaching.getCacheKeyForURL("index.html"));
    

    我遇到了同样的问题,我在这里找到了解决方案:https://github.com/vuejs/vue-cli/issues/717#issuecomment-382079361

    【讨论】:

      猜你喜欢
      • 2012-02-13
      • 1970-01-01
      • 2012-02-05
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      • 2013-05-25
      • 2016-06-07
      • 1970-01-01
      相关资源
      最近更新 更多