Angular无法注册ServiceWorker:获取脚本时收到错误的HTTP响应代码(404) [英] Angular Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script
问题描述
我正在使用Firebase在Angular PWA中进行推送通知,并且正在跟踪链接。 。
单击允许按钮后,它在控制台上引发错误:
无法注册ServiceWorker:获取脚本时收到错误的HTTP响应代码(404)。
代码
:
消息/失败的serviceworker注册
消息
:
消息:我们无法注册默认服务工作者。无法注册ServiceWorker:获取脚本时收到错误的HTTP响应代码(404)。 (消息/失败的serviceworker注册)。
堆栈
:
FirebaseError:消息传递:我们无法注册默认服务人员。无法注册ServiceWorker:获取脚本时收到错误的HTTP响应代码(404)。 (消息/失败的服务工作人员注册)。请访问
我的应用程序和环境文件夹包含以下文件:
我的app.component.ts文件是
从 @ angular / core导入{Component,OnInit};
进口*作为 firebase的firebase;
从 angularfire2 /数据库导入{AngularFireDatabase,AngularFireList};
//从 angularfire2 /已弃用数据库中导入{AngularFireDatabase,FirebaseListObservable,FirebaseObjectObservable};
从 ./push.service导入{PushService};
@Component({
选择器:'app-root',
templateUrl:'./app.component.html',
styleUrls:['./ app.component.scss']
})
出口类AppComponent {
//声明使用的变量
消息传递:任何
token:any //存储当前令牌ID实例生成的
项:AngularFireList< any []>
itemsDisplay:AngularFireList< any []> //可以在模板视图中看到的列表(可选。可以使用项本身)
itemsArr:any [] //存储从Firebase数据库中检索到的令牌ID
hideToken:boolean = false
//通知对象
pushData:任何= {
'notification':{
title: Background Message Title,
body: Background Message正文
},
to:
}
构造函数(公共db:AngularFireDatabase,私有pushService:PushService){
//创建一个可观察到的Firebase列表并调用其中的数据
this.itemsDisplay = db.list('/ items')
//声明消息传递$ b的属性值$ b this.messaging = firebase.messaging();
//检查令牌刷新
this.messaging.onTokenRefresh(function(){
this.messaging.getToken()
.then(function(refreshedToken) {
console.log('令牌刷新。');
})
.catch(function(err){
console.log('无法检索刷新的令牌', err);
});
});
// //分别获取Firebase数据并获取令牌ID值
this.itemsArr = [] //重新初始化数组以防止数据重复
this.items = this.db.list(' / items');
this.items.valueChanges()。subscribe(snapshots => {
console.log(snapshots);
//snapshots.forEach(snapshot => {
// console.log(嘿,快照... +快照);
// this.itemsArr.push(snapshot);
//});
});
// console.log(this.itemsArr)
}
//检查令牌订阅中的重复项
checkToken(token,arr){
console.log(内部检查令牌功能)
console.log(arr)
console.log(令牌)
让计数器:number = 0
for(var i = 0; i< arr.length; i ++){
if(arr [i] ===令牌){
counter ++
}
}
console.log (计数器值,计数器)
返回计数器
}
//通过事件生成推送
generatePush(){
console.log( 内部推送功能)
console.log(this.pushData.to)
if(this.pushData.to ===){
console.log(没有可用令牌)
return
}
this.pushService.generatePush(this.pushData)
.subscribe(data => {console.log(成功发布)}},错误=> console.log(err))
}
//从Firebase数据库获取数据的功能
getDataF romFb(){
this.hideToken = true
}
ngOnInit(){
//提示用户授予加载组件通知的权限
const self = this
this.items = this.db.list('/ items')
this.messaging.requestPermission()
.then(function(){
控制台.log('已授予通知权限。');
self.messaging.getToken()
.then(function(currentToken){
if(currentToken){
self.token = currentToken
self.pushData.to = self.token
console.log(self.pushData.to)
//设置超时时间以使所有数据都能被加载
setTimeout(()= > {
if(self.checkToken(self.token,self.itemsArr)=== 0){
console.log(推送事件)
// self.items。 push({tokenID:currentToken})
} else {
console.log(用户已被订阅)
}
},6500)
//显示当前令牌数据
console.log( currentToken:,currentToken);
console.log(存储令牌:,self.token);
} else {
//显示权限请求。 console.log(’没有可用的实例ID令牌。请求获得生成权限的权限。’);
}
})
.catch(function(err){
console.log('检索令牌时发生错误。',err);
}) ;
}}
.catch(function(err){
console.log('无法获得通知权限。',err);
})
//处理传入的消息。在以下情况下调用:
//-当应用程序将焦点移至
//时收到一条消息//用户单击由服务工作人员 messaging.setBackgroundMessageHandler处理程序创建的应用程序通知。
this.messaging.onMessage(function(payload){
console.log(收到邮件。,有效载荷);
});
}
}
我的firebase-messaging-sw。 js文件是:
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-app .js');
importScripts(’https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js’);
firebase.initializeApp({
messagingSenderId':'850143277209'//再次运行它会显示错误
});
var messages = firebase.messaging();
currentMessage = new BehaviorSubject(null);
//处理后台通知
//如果要自定义在后台收到的通知(Web应用程序已关闭或不在浏览器焦点中),则应该实现此可选方法
messages.setBackgroundMessageHandler(function(payload){
console.log('[firebase-messaging-sw.js]收到背景消息',有效负载);
//自定义这里的通知
var notificationTitle ='背景消息标题';
var notificationOptions = {
正文:'背景消息正文。'
};
return self.registration.showNotification(notificationTitle,
notificationOptions);
});
我的Angular.json文件为:
{
$ schema: ./node_modules/@angular/cli/lib/config/schema.json,
version:1 ,,
newProjectRoot:项目,
项目:{
beautyOfSoul:{
root:,
sourceRoot: src ,
projectType:应用程序,
前缀: app,
schematics:{
@ schematics / angular:component:{
styleext: scss
}
},
architect:{
build:{
builder: @angular -devkit / build-angular:browser,
选项:{
outputPath: dist / beautyOfSoul,
index: src / index.html,
main: src / main.ts,
polyfills: src / polyfills.ts,
tsConfig: src / tsconfig.app.json,
资产:[
src / favicon.ico,
src / assets,
src / assets / manifest.json,
src / manifest.json,
src / firebase-messaging-sw.js
] ,
样式:[
src / styles.scss
],
脚本:[]
},
配置 :{{
制作:{
fileReplacements:{
替换: src / environments / environment.ts,
with: src / environments /environment.prod.ts
}],
optimization:true,
outputHashing: all,
sourceMap:false,
extractCss:true,
namedChunks:false,
aot:正确,
extractLicenses:正确,
vendorChunk:错误,
buildOptimizer:正确,
serviceWorker:正确
}
}
},
serve:{
builder: @ angular-devkit / build-angular:dev-server,
options:{
browserTarget: beautyOfSoul:build
},
configuration:{
production:{
browserTarget:灵魂之美:build:production
}
}
},
extract-i18n:{
builder: @ angular-devkit / build-angular: extract-i18n,
选项:{
browserTarget: beautyOfSoul:build
}
},
test:{
builder: @ angular-devkit / build-angular:karma,
options:{
main: src / test.ts,
polyfills : src / polyfills.ts,
tsConfig: src / tsconfig.spec.json,
karmaConfig: src / karma.conf.js,
样式:[[
src / styles.scss
],
脚本:[],
资产:[
src / favicon.ico,
src / assets,
src / manifest.json,
src / firebase-messaging-sw.js
]
}
},
lint:{
builder: @ angular-devkit / build-angular:tslint,
options:{
tsConfig:[
src / tsconfig.app.json,
src / tsconfig.spec.json
],
排除: [
** / node_modules / **
]
}
}
}
},
beautyOfSoul-e2e: {
root: e2e /,
projectType: application,
architect:{
e2e:{
builder: @ angular-devkit / build-angular:protractor,
options:{
protractorConfig: e2e / protractor.conf.js,
devServerTarget: beautyOfSoul:serve
},
configuration:{
production:{
devServerTarget: beautyOfSoul:serve:production
}
}
},
lint:{
builder: @ angular-devkit / build-angular:tslint,
options:{
tsConfig: e2e / tsconfig.e2e.json,
exclude:[
** / node_modules / **
]
}
}
}
}
},
defaultPr oject: beautyOfSoul
}
我的网络标签为:
< a href = https://i.stack.imgur.com/OqCvU.png rel = nofollow noreferrer>
我的服务人员标签为:
解决方案我在React项目中遇到了类似的问题,对我来说解决方案是手动将我自己的js文件注册为服务工作者。
navigator.serviceWorker.register('./ your-serviceworker-file.js ')
.then((registration)=> {
messages.useServiceWorker(registration);
//请求权限并获得令牌。....
});
在firebase初始化中运行该代码为我解决了这个问题。
I am doing Push notifications in Angular PWA with Firebase and I am following a link to do so. https://medium.com/@tariqueejaz/progressive-web-app-push-notifications-making-the-web-app-more-native-in-nature-a167af22e004
I am using Angular 6 and have setup the code for everything. when I am trying to run it, then it is showing me a pop up .
After clicking on Allow button, it is throwing an error on console:
Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script." code : "messaging/failed-serviceworker-registration" message : "Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration)." stack : "FirebaseError: Messaging: We are unable to register the default service worker. Failed to register a ServiceWorker: A bad HTTP response code (404) was received when fetching the script. (messaging/failed-serviceworker-registration).↵ at http://localhost:4200/vendor.js:106604:32↵ at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:4200/polyfills.js:2710:26)↵ at Object.onInvoke (http://localhost:4200/vendor.js:35701:33)↵ at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invoke (http://localhost:4200/polyfills.js:2709:32)↵ at Zone.push../node_modules/zone.js/dist/zone.js.Zone.run (http://localhost:4200/polyfills.js:2460:43)↵ at http://localhost:4200/polyfills.js:3194:34↵ at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:2743:31)↵ at Object.onInvokeTask (http://localhost:4200/vendor.js:35692:33)↵ at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (http://localhost:4200/polyfills.js:2742:36)↵ at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (http://localhost:4200/polyfills.js:2510:47)" proto : Error
My project Structure is:
My app and environment folder consists of following files:
My app.component.ts file is
import {Component, OnInit} from '@angular/core'; import * as firebase from 'firebase'; import {AngularFireDatabase, AngularFireList} from 'angularfire2/database'; //import {AngularFireDatabase, FirebaseListObservable, FirebaseObjectObservable} from 'angularfire2/database-deprecated'; import {PushService} from './push.service'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.scss'] }) export class AppComponent { // Declare the variables used messaging: any token: any // Stores the current token ID instance generated items: AngularFireList<any[]> itemsDisplay: AngularFireList<any[]> // List observable for template view (Optional. items itself can be used) itemsArr: any[] // Stores the token IDs retrieved from the firebase database hideToken: boolean = false // Notificayion object pushData: any = { 'notification': { "title": "Background Message Title", "body": "Background Message Body" }, "to": "" } constructor(public db: AngularFireDatabase, private pushService: PushService) { // Creates a Firebase List Observable and calls the data in it this.itemsDisplay = db.list('/items') // Declaring the property value of messaging this.messaging = firebase.messaging(); // Check for token refresh this.messaging.onTokenRefresh(function() { this.messaging.getToken() .then(function(refreshedToken) { console.log('Token refreshed.'); }) .catch(function(err) { console.log('Unable to retrieve refreshed token ', err); }); }); // Obtaining the firebase data and retrieving token ID values separately this.itemsArr = [] // Reinitialize the array to prevent data duplication this.items = this.db.list('/items'); this.items.valueChanges().subscribe(snapshots => { console.log(snapshots); //snapshots.forEach(snapshot => { // console.log("Hey ,, snapshot......"+snapshot); // this.itemsArr.push(snapshot); // }); }); // console.log(this.itemsArr) } // Check for duplicates in token subscription checkToken(token, arr) { console.log("Inside check token function") console.log(arr) console.log(token) let counter: number = 0 for (var i = 0; i < arr.length; i++) { if (arr[i] === token) { counter++ } } console.log("Counter value", counter) return counter } // Generate Push through an event generatePush() { console.log("Inside push function") console.log(this.pushData.to) if (this.pushData.to === "") { console.log("No token available") return } this.pushService.generatePush(this.pushData) .subscribe(data => {console.log("Succesfully Posted")}, err => console.log(err)) } // Function to get the data from Firebase Database getDataFromFb() { this.hideToken = true } ngOnInit() { // Prompt user to grant permission for notifications on loading components const self = this this.items = this.db.list('/items') this.messaging.requestPermission() .then(function() { console.log('Notification permission granted.'); self.messaging.getToken() .then(function(currentToken) { if (currentToken) { self.token = currentToken self.pushData.to = self.token console.log(self.pushData.to) // Set a timeout so as to enable all the data to be loaded setTimeout(() => { if (self.checkToken(self.token, self.itemsArr) === 0) { console.log("Push occurrence") // self.items.push({tokenID: currentToken}) } else { console.log("User is already subscribed") } }, 6500) // Displays the current token data console.log("currentToken: ", currentToken); console.log("Stored token: ", self.token); } else { // Show permission request. console.log('No Instance ID token available. Request permission to generate one.'); } }) .catch(function(err) { console.log('An error occurred while retrieving token.', err); }); }) .catch(function(err) { console.log('Unable to get permission to notify. ', err); }) // Handle incoming messages. Called when: // - a message is received while the app has focus // - the user clicks on an app notification created by a sevice worker `messaging.setBackgroundMessageHandler` handler. this.messaging.onMessage(function(payload) { console.log("Message received. ", payload); }); } }
My firebase-messaging-sw.js file is:
importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-app.js'); importScripts('https://www.gstatic.com/firebasejs/3.5.0/firebase-messaging.js'); firebase.initializeApp({ 'messagingSenderId': '850143277209' // run it again show me error }); var messaging = firebase.messaging(); currentMessage = new BehaviorSubject(null); // Handle Background Notifications // If you would like to customize notifications that are received in the background (Web app is closed or not in browser focus) then you should implement this optional method messaging.setBackgroundMessageHandler(function (payload) { console.log('[firebase-messaging-sw.js] Received background message ', payload); // Customize notification here var notificationTitle = 'Background Message Title'; var notificationOptions = { body: 'Background Message body.' }; return self.registration.showNotification(notificationTitle, notificationOptions); });
My Angular.json file is:
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "beautyOfSoul": { "root": "", "sourceRoot": "src", "projectType": "application", "prefix": "app", "schematics": { "@schematics/angular:component": { "styleext": "scss" } }, "architect": { "build": { "builder": "@angular-devkit/build-angular:browser", "options": { "outputPath": "dist/beautyOfSoul", "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.app.json", "assets": [ "src/favicon.ico", "src/assets", "src/assets/manifest.json", "src/manifest.json", "src/firebase-messaging-sw.js" ], "styles": [ "src/styles.scss" ], "scripts": [] }, "configurations": { "production": { "fileReplacements": { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" }], "optimization": true, "outputHashing": "all", "sourceMap": false, "extractCss": true, "namedChunks": false, "aot": true, "extractLicenses": true, "vendorChunk": false, "buildOptimizer": true, "serviceWorker": true } } }, "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "beautyOfSoul:build" }, "configurations": { "production": { "browserTarget": "beautyOfSoul:build:production" } } }, "extract-i18n": { "builder": "@angular-devkit/build-angular:extract-i18n", "options": { "browserTarget": "beautyOfSoul:build" } }, "test": { "builder": "@angular-devkit/build-angular:karma", "options": { "main": "src/test.ts", "polyfills": "src/polyfills.ts", "tsConfig": "src/tsconfig.spec.json", "karmaConfig": "src/karma.conf.js", "styles": [ "src/styles.scss" ], "scripts": [], "assets": [ "src/favicon.ico", "src/assets", "src/manifest.json", "src/firebase-messaging-sw.js" ] } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": [ "src/tsconfig.app.json", "src/tsconfig.spec.json" ], "exclude": [ "**/node_modules/**" ] } } } }, "beautyOfSoul-e2e": { "root": "e2e/", "projectType": "application", "architect": { "e2e": { "builder": "@angular-devkit/build-angular:protractor", "options": { "protractorConfig": "e2e/protractor.conf.js", "devServerTarget": "beautyOfSoul:serve" }, "configurations": { "production": { "devServerTarget": "beautyOfSoul:serve:production" } } }, "lint": { "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": "e2e/tsconfig.e2e.json", "exclude": [ "**/node_modules/**" ] } } } } }, "defaultProject": "beautyOfSoul" }
My Network tab is:
My service worker tab is:
解决方案I got a similar issue in React project, and for me the solution was to manually register my own js file as a serviceworker.
navigator.serviceWorker.register('./your-serviceworker-file.js') .then((registration) => { messaging.useServiceWorker(registration); // Request permission and get token..... });
Running that code in the firebase initialization solved the issue for me.
这篇关于Angular无法注册ServiceWorker:获取脚本时收到错误的HTTP响应代码(404)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!