Service Worker未向运行在Firebase Functions上的Nuxt.js(通用)构建的应用程序注册。
我目前正在尝试使用Nuxt.js通用模式和Firebase函数构建原型Web应用程序。 该应用程序使用带有nuxt官方pwa模块的service worker来管理已登录用户的会话,以便客户端可以将带有授权标头的请求发送到服务器,服务器将通过Firebase身份验证来验证用户会话。
我已经尝试使用yarn run build
和yarn run start
在本地服务器上运行它,并确保服务工作者已经正确注册并可以正常工作。
但是,当我尝试使用firebase serve
检查相同的操作时,在浏览器上收到以下错误。
A bad HTTP response code (404) was received when fetching the script.
Failed to load resource: net::ERR_INVALID_RESPONSE
dcbac67bb39a765db27a.js:1 Service worker registration failed: TypeError: Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script.
我还发现服务工作者没有将会话数据发送到服务器。当我使用firebase deploy
将源部署到生产中时,完全可以复制相同的东西。
当我用yarn create nuxt-app
,yarn run build
和firebase serve
彻底清理项目时,甚至会发生这种情况。 “ sw.js”文件指示Chrome开发者工具上的状态失败。
我不确定是否担心,但是我的Firebase是否在Spark计划上。
我的项目树。
.
├── firebase.json
├── firestore.indexes.json
├── firestore.rules
├── functions
│ ├── index.js
│ ├── nuxt
│ │ ├── App.js
│ │ ├── axios.js
│ │ ├── client.js
│ │ ├── components
│ │ ├── dist
│ │ ├── empty.js
│ │ ├── index.js
│ │ ├── loading.html
│ │ ├── middleware.js
│ │ ├── router.js
│ │ ├── server.js
│ │ ├── store.js
│ │ ├── sw.plugin.js
│ │ ├── sw.template.js
│ │ ├── utils.js
│ │ └── views
│ ├── package-lock.json
│ ├── package.json
│ └── yarn.lock
├── public
└── src
├── assets
├── components
├── jest.config.js
├── layouts
├── middleware
├── nuxt.config.js
├── package.json
├── pages
├── plugins
├── server
├── static
│ └── sw.js
├── store
└── test
└── yarn.lock
src / static / sw.js
importScripts('/_nuxt/workbox.4c4f5ca6.js')
workbox.precaching.precacheAndRoute([
{
"url": "/_nuxt/021e1640b53136b75c48.js",
"revision": "2753e747206d803c793b59a324c1931b"
},
{
"url": "/_nuxt/03c9e340d8692d1403a9.js",
"revision": "2b882d73d20a0b2cfd318e9e05d3496e"
},
{
"url": "/_nuxt/78bddfa6b6a4919b78d6.js",
"revision": "70312f6623089e3b4aa6454120c1e177"
},
{
"url": "/_nuxt/85c817abccdd40162004.js",
"revision": "45448f8709d01af59bb125a1d06be23a"
},
{
"url": "/_nuxt/8654a518d0f3e326c9a6.js",
"revision": "a42426f5e7b458acc6fdf0e9e48c7d35"
},
{
"url": "/_nuxt/95b421159066eff9e318.js",
"revision": "efd1643042f804defa7212979867558a"
},
{
"url": "/_nuxt/9b487bf2df1190b68565.js",
"revision": "78837d0e624deccc85761b44f9ede9be"
},
{
"url": "/_nuxt/ce59381752309c170d41.js",
"revision": "d3e50bf27891c4efa6dff5076a0772a6"
},
{
"url": "/_nuxt/d8fa6ae5ca14331879f6.js",
"revision": "5da6698c9359df803243ecc44519b610"
},
{
"url": "/_nuxt/dcbac67bb39a765db27a.js",
"revision": "9505aa84ddb2a70b826d324433daff36"
},
{
"url": "/_nuxt/dee89eef613849499c7f.js",
"revision": "43117ed819efe3d00c963dd655894d5f"
}
], {
"cacheId": "justtest",
"directoryIndex": "/",
"cleanUrls": false
})
workbox.clientsClaim()
workbox.skipWaiting()
workbox.routing.registerRoute(new RegExp('/_nuxt/.*'), workbox.strategies.cacheFirst({}), 'GET')
workbox.routing.registerRoute(new RegExp('/.*'), workbox.strategies.networkFirst({}), 'GET')
functions / index.js
const functions = require("firebase-functions")
const { Nuxt } = require("nuxt")
const express = require("express")
const app = express()
const nuxt = new Nuxt({ buildDir: "nuxt", dev: false })
function handleRequest(req, res) {
res.setHeader('Cache-Control', 'private')
return new Promise((resolve, reject) => {
nuxt.render(req, res, promise => {
promise.then(resolve).catch(reject)
})
})
}
app.use(handleRequest)
exports.ssr = functions.https.onRequest(app)
预期的行为是,当我使用firebase serve
和firebase deploy
运行应用程序时,sw.js可以正常工作。
答案 0 :(得分:0)
我设法找到了解决方案。我可能误解了服务人员的行为。
我只是离开我的解决方案,以便可以帮助遇到同样情况的人。
首先,我根本不了解服务工作者js文件/static/sw.js
,因为它是由yarn run build
自动创建的,当我使用yarn run start
运行应用程序时,一切工作正常。因此,我认为我根本不必关心该文件。
但是我发现/static
目录中的所有文件都必须放在/public
目录中,该目录将由firebase托管,以便客户端可以找到并下载它们。我猜想当我使用yarn run start
时,/static
目录中的文件将由开发服务器托管。
我还意识到服务工作者是静态的javascript文件,它们必须由Firebase托管而不是由Firebase函数托管。我曾经尝试将它们放在dist/client
中,但这没有任何意义。它必须放置在/public
目录中。
我终于使它与以下项目树一起使用。运行yarn run build
时,我将/src/static
中的所有内容复制到/public
中,以使用Firebase托管对其进行托管。
.
├── firebase.json
├── functions
│ ├── index.js
│ ├── nuxt
│ │ ├── App.js
│ │ ├── axios.js
│ │ ├── client.js
│ │ ├── components
│ │ ├── dist
│ │ ├── empty.js
│ │ ├── index.js
│ │ ├── loading.html
│ │ ├── middleware.js
│ │ ├── router.js
│ │ ├── server.js
│ │ ├── store.js
│ │ ├── sw.plugin.js
│ │ ├── sw.template.js
│ │ ├── utils.js
│ │ └── views
│ ├── package-lock.json
│ ├── package.json
│ └── yarn.lock
├── public
│ ├── favicon.ico
│ ├── sw-firebase-auth.js
│ └── sw.js
└── src
├── assets
├── components
├── layouts
├── middleware
├── nuxt.config.js
├── package.json
├── pages
├── plugins
├── server
├── static
│ ├── favicon.ico
│ ├── sw-firebase-auth.js
│ └── sw.js
├── store
└── yarn.lock
这是我的sw-firebase-auth.js
。 (我使用Browserify编译了此脚本,以使其正常工作。)
var firebase = require('firebase')
// Initialize the Firebase app in the service worker script.
firebase.initializeApp({
apiKey: '*************',
authDomain: '*************',
databaseURL: '*************',
projectId: '*************',
storageBucket: '*************',
messagingSenderId: '*************'
})
/**
* Returns a promise that resolves with an ID token if available.
* @return {!Promise<?string>} The promise that resolves with an ID token if
* available. Otherwise, the promise resolves with null.
*/
const getIdToken = () => {
return new Promise((resolve) => {
const unsubscribe = firebase.auth().onAuthStateChanged((user) => {
unsubscribe();
if (user) {
user.getIdToken().then((idToken) => {
resolve(idToken)
}, () => {
resolve(null)
});
} else {
resolve(null)
}
})
})
}
const getOriginFromUrl = (url) => {
const pathArray = url.split('/');
const protocol = pathArray[0];
const host = pathArray[2];
return protocol + '//' + host;
};
self.addEventListener('fetch', (event) => {
const requestProcessor = (idToken) => {
let req = event.request;
if (self.location.origin == getOriginFromUrl(event.request.url) &&
(self.location.protocol == 'https:' ||
self.location.hostname == 'localhost') &&
idToken) {
const headers = new Headers();
for (let entry of req.headers.entries()) {
headers.append(entry[0], entry[1]);
}
headers.append('Authorization', 'Bearer ' + idToken);
try {
req = new Request(req.url, {
method: req.method,
headers: headers,
mode: 'same-origin',
credentials: req.credentials,
cache: req.cache,
redirect: req.redirect,
referrer: req.referrer,
body: req.body,
bodyUsed: req.bodyUsed,
context: req.context
});
} catch (e) {
console.log(e)
}
}
return fetch(req);
};
event.respondWith(getIdToken().then(requestProcessor, requestProcessor));
});
self.addEventListener('activate', event => {
event.waitUntil(clients.claim());
})
这也是nuxt.conf.js
中的工作箱配置。它与使用importScripts
的官方pwa-module配合良好。
workbox: {
importScripts: [
'sw-firebase-auth.js'
]
}
我希望这会对某人有所帮助。
答案 1 :(得分:0)
如果要通过SSR部署Nuxt.js 2.12.2项目,则项目目录中可能有.nuxt
文件夹。将其删除,并根据需要从nuxt.config.js
配置Workbox,然后运行nuxt build
,npm run build
或yarn build
。
如果它在本地计算机上可用,则可以尝试清除服务器上的缓存,以确保所有旧的.nuxt
文件夹都已消失并重新部署项目。
希望这对您有帮助>