部署到生产 Netlify 的 Vue CLI 3 PWA 给出了工作箱错误:bad-precaching-response ..._redirects?__WB_REVISION__...404

Ste*_*sel 4 redirect vue.js progressive-web-apps netlify workbox

这个问题只发生在 Netlify 的生产环境中。它不会出现在开发环境中。通常,我会潜伏并搜索以找到答案,或者将相关答案中的一些东西放在一起,但是这个让我很难过......

我有一个在 Netlify 上运行的 Vue CLI 项目,它设置了一个过去部署过的 PWA。Service Worker 应该正在运行,并且可以安装该应用程序以供离线使用。

现在它在控制台中给了我这个错误:

Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"https://<domain>/_redirects?__WB_REVISION__=d38a2b58df330c85e0029eecf71d7c26","status":404}]
    at l.o (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1749)
    at async Promise.all (index 0)
    at async l.install (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1221)
Run Code Online (Sandbox Code Playgroud)

因此,当工作箱执行此操作时,它似乎用 404 将我的“_redirects”文件踢出。

我曾尝试将 _redirects 更改为 netlify.toml 文件,其中重定向内容在 .toml 文件中的格式正确,但它仍然失败,这是相同的错误消息,只是“netlify.toml”在错误中替换了“_redirects” .

我还尝试将相同的代码库部署到新的 Netlify 版本(认为这可能是他们资源的缓存问题),但问题仍然存在。

我猜想这可能是 Workbox 无法编译资产或为与重定向相关的文件提供错误名称的问题。但这也没有意义,因为当我在本地和 Netlify 生产环境中运行 build 命令时,它们都应该由托管在 cdn 上的相同代码处理。

这是从工作箱发送错误的代码块:

    const isValidResponse = cacheWillUpdateCallback ?
      // Use a callback if provided. It returns a truthy value if valid.
      cacheWillUpdateCallback({event, request, response}) :
      // Otherwise, default to considering any response status under 400 valid.
      // This includes, by default, considering opaque responses valid.
      response.status < 400;

    // Consider this a failure, leading to the `install` handler failing, if
    // we get back an invalid response.
    if (!isValidResponse) {
      throw new WorkboxError('bad-precaching-response', {
        url,
        status: response.status,
      });
    }
Run Code Online (Sandbox Code Playgroud)

这是我的 package.json:

{
  "name": "<app-name>",
  "version": "0.2.0",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "lint": "vue-cli-service lint",
    "capacitor-copy": "vue-cli-service capacitor-copy",
    "capacitor-init": "vue-cli-service capacitor-init",
    "capacitor-open": "vue-cli-service capacitor-open",
    "capacitor-update": "vue-cli-service capacitor-update",
    "css:build": "postcss src/css/styles.css -o public/styles.css"
  },
  "dependencies": {
    "@capacitor/cli": "^1.0.0-alpha.38",
    "@capacitor/core": "^1.0.0-alpha.38",
    "@fullhuman/postcss-purgecss": "^1.3.0",
    "axios": "^0.19.1",
    "core-js": "^3.4.4",
    "moment": "^2.24.0",
    "postcss": "^7.0.26",
    "postcss-cli": "^6.1.3",
    "register-service-worker": "^1.6.2",
    "tailwindcss": "^1.1.4",
    "vue": "^2.6.10",
    "vue-router": "^3.1.3",
    "vue-uuid": "^1.1.1",
    "vuex": "^3.1.2"
  },
  "devDependencies": {
    "@vue/cli-plugin-babel": "^4.2.2",
    "@vue/cli-plugin-eslint": "^4.2.2",
    "@vue/cli-plugin-pwa": "^4.2.0",
    "@vue/cli-plugin-router": "^4.2.2",
    "@vue/cli-plugin-vuex": "^4.2.2",
    "@vue/cli-service": "^4.1.0",
    "babel-eslint": "^10.0.3",
    "eslint": "^5.16.0",
    "eslint-plugin-vue": "^5.0.0",
    "vue-cli-plugin-pwa": "^1.0.0-alpha.1",
    "vue-template-compiler": "^2.6.10"
  },
  "eslintConfig": {
    "root": true,
    "env": {
      "node": true
    },
    "extends": [
      "plugin:vue/essential",
      "eslint:recommended"
    ],
    "rules": {},
    "parserOptions": {
      "parser": "babel-eslint"
    }
  },
  "browserslist": [
    "> 1%",
    "last 2 versions"
  ]
}
Run Code Online (Sandbox Code Playgroud)

和我的 manifest.json 文件:

{
    "short_name": "<name>",
    "name": "<name>",
    "description": "I have no idea what I'm doing with these build tools.",
    "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"
        },
        {
            "src": "./img/icons/apple-touch-icon-152x152.png",
            "sizes": "152x152",
            "type": "image/png"
        },
        {
            "src": "./img/icons/favicon-16x16.png",
            "sizes": "16x16",
            "type": "image/png"
        },
        {
            "src": "./img/icons/favicon-32x32.png",
            "sizes": "32x32",
            "type": "image/png"
        },
        {
            "src": "./img/icons/msapplication-icon-144x144.png",
            "sizes": "144x144",
            "type": "image/png"
        },
        {
            "src": "./img/icons/safari-pinned-tab.png",
            "sizes": "144x144",
            "type": "image/png"
        }
    ],
    "start_url": ".",
    "background_color": "#2d3748",
    "display": "standalone",
    "scope": "/",
    "theme_color": "#2d3748"
}
Run Code Online (Sandbox Code Playgroud)

index.html 文件也可能有帮助:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <meta name="theme-color" content="#2d3748"/>
    <link rel="manifest" href="manifest.json">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <link rel="stylesheet" href="<%= BASE_URL %>styles.css">
    <title>NAME</title>
  </head>
  <body>
    <noscript>
      <strong>This app doesn't work at all without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>
    <div id="app"></div>
    <!-- built files will be auto injected -->
  </body>
</html>
Run Code Online (Sandbox Code Playgroud)

老实说,我认为这不是我的代码库的问题。我认为在部署到 netlfiy 时配置生成动态 URL 的工作箱将是一个问题。如前所述,'npm run build' 脚本在我的本地机器上构建没有问题。我很想知道最近是否有人在使用 netlify 或 workbox 时遇到过这种错误。

如有任何帮助,我将不胜感激。

Ste*_*sel 5

我发现了这个问题:这是我在测试时的想法,也发布在其他地方:

我需要发布的构建目录中的 _redirects 文件,但我想从服务工作者用来过滤本地或互联网资产流量的生成清单中排除它。所以我将尝试为 _redirects 指定一个排除项

尝试:更改我的 vue.config.js(vue CLI 项目中 webpack.config 的代理):

module.exports = {
    devServer: {
        host: 'lite.bdfi.test'
    },
    pwa: {
        name: 'BDFI',
        themeColor: '#2d3748',
        msTileColor: '#2d3748',
        appleMobileWebAppCapable: 'no',
        appleMobileWebAppStatusBarStyle: 'default',
        manifestPath: 'manifest.json',
        workboxPluginMode: 'GenerateSW'
        
    }
}
Run Code Online (Sandbox Code Playgroud)

对此:

module.exports = {
    devServer: {
        host: 'lite.bdfi.test'
    },
    pwa: {
        name: 'BDFI',
        themeColor: '#2d3748',
        msTileColor: '#2d3748',
        appleMobileWebAppCapable: 'no',
        appleMobileWebAppStatusBarStyle: 'default',
        manifestPath: 'manifest.json',
        workboxPluginMode: 'InjectManifest',
        workboxOptions: {
            // swSrc is required in InjectManifest mode.
            swSrc: 'service-worker.js',
            // ...other Workbox options...
            exclude: [/_redirects/],
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这意味着我现在正在为 service worker 指定输入,所以我需要从某个地方获取 service worker。这是我的服务工作者(它只是自动生成的一个精简版)

workbox.core.setCacheNameDetails({prefix: "lite-bdfi-app"});

self.addEventListener('message', (event) => {
    
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
});

self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
Run Code Online (Sandbox Code Playgroud)

构建后与注入的清单和工作箱脚本相同:

importScripts("/precache-manifest.54b556dfe16cf1359c2f3257fa76ade9.js", "https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
Run Code Online (Sandbox Code Playgroud)

而且,本地“dist”目录确认省略了“_redirects”文件。

现在我在本地运行这个构建并在本地服务器中启动它,现在它抛出不同的错误。在本地,这是以前从未发生过的……

PrecacheController.mjs:194 Uncaught (in promise) bad-precaching-response: bad-precaching-response :: [{"url":"http://127.0.0.1:8887/css/app.159bf243.css.map?__WB_REVISION__=b04e3357da21d1241e39","status":404}]
    at l.o (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1749)
    at async Promise.all (index 0)
    at async l.install (https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-precaching.prod.js:1:1221)
n @ WorkboxError.mjs:30
o @ PrecacheController.mjs:194
Run Code Online (Sandbox Code Playgroud)

看起来很熟悉,现在有 5 个,都在寻找带有 .map 扩展名的文件……现在我将从清单构建中删除 .map 文件,看看有什么作用:

workboxOptions: {
            // swSrc is required in InjectManifest mode.
            swSrc: 'service-worker.js',
            // ...other Workbox options...
            exclude: [/\.map$/, /_redirects/], //this fixed it.
        }
Run Code Online (Sandbox Code Playgroud)

再次运行构建,检查 dist 文件夹清单,清单中不包含 .map 文件。然后检查清除缓存和本地存储的应用程序的本地版本。没有错误......似乎很有希望。推送到 GitHub。Netlify 构建触发器,不会自动发布,因此请访问暂存链接。在寻找 _redirects 文件的页面加载时不再出现错误。检查“/invalid-url”的重定向,它会按预期转移到 404 页面。发布部署后,我现在可以将应用程序作为 PWA 安装在我的桌面上。

问题已为我解决。我希望这可以帮助将来遇到同样问题的人。

  • 它帮助了我。谢谢。 (2认同)