Как кэшировать другие маршруты для автономного просмотра?

Я настраиваю прогрессивное веб-приложение, поддерживающее автономный просмотр.

Я уже настроил автономный просмотр для своего основного маршрута ('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, {});

person frost kazuma    schedule 02.10.2019    source источник
comment
Где вы определили офлайн-стратегию? Я вижу только ваш веб-манифест, но не код сервисного работника.   -  person Francesco    schedule 02.10.2019
comment
Привет, отредактировал вопрос, я использую только автоматически сгенерированный service-worker.js из Vue CLI 3, я считаю, что должен сделать свой собственный?   -  person frost kazuma    schedule 02.10.2019
comment
Могу ли я спросить, сработал ли какой-либо из ответов или вы нашли решение?   -  person themthem    schedule 13.04.2021


Ответы (3)


Есть более простое решение, которое не требует использования InjectManifest.

Просто добавьте это в свой файл vue.config.js:

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

Он автоматически добавит необходимый код в ваш сервис-воркер:

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

У меня была та же проблема, и я нашел решение здесь: https://github.com/vuejs/vue-cli/issues/717#issuecomment-382079361

person clem    schedule 18.12.2019

Всем, кто также использует vue/cli-pligin-pwa и vue-cli 3, я решил эту проблему.

vue/cli-pligin-pwa выполняет свою работу по кэшированию ваших js-файлов для автономного использования вашего веб-приложения.

но поскольку вы используете одностраничное приложение, вам придется установить какой-то запасной вариант.

Запрос страницы например, (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()
    }
})
person frost kazuma    schedule 22.10.2019

Проблема в том, что ваш сервис-воркер не знает, какие активы кэшировать. Каково значение self.__precacheManifest? (вероятно, файл веб-манифеста).

Вам нужно будет настроить рабочий ящик, чтобы иметь некоторые ресурсы для метода precacheAndRoute, так как это будет указывать сервис-воркеру, какие файлы кэшировать и когда. Что-то вроде:

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

По умолчанию сервис-воркер не знает, какие ресурсы или HTTP-ответы нужно кэшировать, поэтому мы должны определить и реализовать стратегию кэширования в соответствии с нашими требованиями.

Я написал статью о сервис-воркерах и доступных стратегии кэширования. Посмотрите, если хотите углубить тему.

person Francesco    schedule 02.10.2019
comment
привет, я посмотрю на эту статью, я считаю, что мне также нужно немного больше исследований с workbox и сервисным работником, прежде чем я интегрирую его в vue.js, спасибо! - person frost kazuma; 02.10.2019
comment
Если ответ помог вам продолжить или ответил на ваш вопрос, вы должны отметить его как решенный. +1 в конце концов, если вы чему-то научились из этого. - person Francesco; 02.10.2019