Angular Service Worker SwUpdate.available 未触发
Angular Service Worker SwUpdate.available not triggered
我很难将 angulars service worker 集成到我的应用程序中。我按照指南进行操作,到目前为止它一直有效。我可以在我的主屏幕上创建一个快捷方式并启动到我的应用程序中。问题是我的应用程序不知何故没有更新。如果我更改按钮的名称,构建应用程序并将其放到我的服务器上,应用程序仍然显示旧版本,直到我按 F5(重新启动应用程序也无济于事)。
我试图将以下代码放入我的应用程序的 ngOnInot 中,但它没有帮助
ngOnInit() {
if (this._SwUpdate.isEnabled) {
setInterval( () => {
this._SwUpdate.checkForUpdate().then(() => console.log('checking for updates'));
}, this.updateInterval);
this._SwUpdate.available.subscribe(() => {
console.log('update found');
this._SwUpdate.activateUpdate().then(() => {
console.log('updated');
window.location.reload();
});
});
}
}
该应用程序 运行 在我的 apache2 linux 机器上运行。我的 apache 是否在缓存某些东西,或者为什么我的应用程序没有意识到有新版本?
提前感谢您的帮助:)
编辑:
我的ngsw-config.json
{
"index": "/index.html",
"assetGroups": [{
"name": "roomPlan",
"installMode": "prefetch",
"resources": {
"files": [
"/index.html",
"/*.css",
"/*.js"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**"
]
}
}]
}
编辑 2:
如果我 运行 使用本地应用程序 "http-server" 它可以工作,但是当我将文件复制到我的 apache 时它没有检测到更新。在网络选项卡中,我可以看到间隔有效,应用程序每 3 秒从服务器获取一个新的 "ngsw.json"。如果我更新我的应用程序,我可以看到 "ngsw.json" 的响应中有新的哈希值。之后浏览器从我的服务器加载新的 "index.html" 和 "main.***.js" 但应用程序不应用新版本。根据我的代码,它应该显示 "update found" 但什么也没有发生。
您可能需要告诉服务人员检查服务器是否有更新,我通常为此使用服务:
export class UpdateService {
constructor(public updates: SwUpdate) {
if (updates.isEnabled) {
interval(6 * 60 * 60).subscribe(() => updates.checkForUpdate()
.then(() => console.log('checking for updates')));
}
}
public checkForUpdates(): void {
this.updates.available.subscribe(event => this.promptUser());
}
private promptUser(): void {
console.log('updating to new version');
this.updates.activateUpdate().then(() => document.location.reload());
}
在你的app-component.ts
中:
constructor(private sw: UpdateService) {
// check the service worker for updates
this.sw.checkForUpdates();
}
无论出于何种原因,Angular 有时无法正确注册 service worker。所以你可以修改 `main.ts` :
替换:
platformBrowserDynamic().bootstrapModule(AppModule);
与:
platformBrowserDynamic().bootstrapModule(AppModule).then(() => {
if ('serviceWorker' in navigator && environment.production) {
navigator.serviceWorker.register('ngsw-worker.js');
}
}).catch(err => console.log(err));
更改您的应用程序需要使用此方法 activateUpdate(
import { SwUpdate } from '@angular/service-worker';
export class AppComponent implements OnInit {
constructor(private swUpdate: SwUpdate) { }
ngOninit() {
this.swUpdate.available.subscribe(event => {
console.log('A newer version is now available. Refresh the page now to update the cache');
});
this.swUpdate.checkForUpdate()
}
}
检查这个 Link:https://angular.io/guide/service-worker-getting-started
在堆栈上的所有其他解决方案都不起作用后,我开始调试 angular 的 ngsw-worker.js 脚本。我跟踪了更新逻辑并以 "PrefetchAssetGroup" 方法结束。每次调用方法时我都插入了日志记录,然后我意识到它一直在尝试缓存我的 favicon.ico。
我检查了 favicon.ico 在我的 ngsw.json 中的位置,发现网站图标不在那里。一旦我将图标放在该位置,一切就开始正常工作了。
这对我来说适用于所有设备mac/windows/ios/android
export class PwaUpdateService {
updateSubscription;
constructor(public updates: SwUpdate) {
}
public checkForUpdates(): void {
this.updateSubscription = this.updates.available.subscribe(event => this.promptUser());
if (this.updates.isEnabled) {
// Required to enable updates on Windows and ios.
this.updates.activateUpdate();
interval(60 * 60 * 1000).subscribe(() => {
this.updates.checkForUpdate().then(() => {
// console.log('checking for updates');
});
});
}
// Important: on Safari (ios) Heroku doesn't auto redirect links to their https which allows the installation of the pwa like usual
// but it deactivates the swUpdate. So make sure to open your pwa on safari like so: https://example.com then (install/add to home)
}
promptUser(): void {
this.updates.activateUpdate().then(() => {
window.location.reload();
});
}
}
要检查 Angular 的更新版本是否可用,您可以从任何组件调用以下方法,或者只需复制 app.component
.[=13= 中的 IsNewerVersionAvailable
方法]
export class DataService {
constructor(private http: HttpClient, private swUpdate: SwUpdate) { }
private available: boolean = false;
IsNewerVersionAvailable() {
if (this.swUpdate.isEnabled) {
this.swUpdate.available.subscribe(() => {
this.available = true;
});
console.log(this.available);
}
return this.available;
}
}
我在 angular 文档中找到了以下信息:
https://angular.io/guide/service-worker-devops#debugging-the-angular-service-worker
总结:
angular 站点上有一个有用的端点可以显示 service worker 状态:
http://site-url/ngsw/state
将 /ngsw/state
附加到您的站点地址。如果服务有问题,它应该在那里显示。
我很难将 angulars service worker 集成到我的应用程序中。我按照指南进行操作,到目前为止它一直有效。我可以在我的主屏幕上创建一个快捷方式并启动到我的应用程序中。问题是我的应用程序不知何故没有更新。如果我更改按钮的名称,构建应用程序并将其放到我的服务器上,应用程序仍然显示旧版本,直到我按 F5(重新启动应用程序也无济于事)。
我试图将以下代码放入我的应用程序的 ngOnInot 中,但它没有帮助
ngOnInit() {
if (this._SwUpdate.isEnabled) {
setInterval( () => {
this._SwUpdate.checkForUpdate().then(() => console.log('checking for updates'));
}, this.updateInterval);
this._SwUpdate.available.subscribe(() => {
console.log('update found');
this._SwUpdate.activateUpdate().then(() => {
console.log('updated');
window.location.reload();
});
});
}
}
该应用程序 运行 在我的 apache2 linux 机器上运行。我的 apache 是否在缓存某些东西,或者为什么我的应用程序没有意识到有新版本?
提前感谢您的帮助:)
编辑:
我的ngsw-config.json
{
"index": "/index.html",
"assetGroups": [{
"name": "roomPlan",
"installMode": "prefetch",
"resources": {
"files": [
"/index.html",
"/*.css",
"/*.js"
]
}
}, {
"name": "assets",
"installMode": "lazy",
"updateMode": "prefetch",
"resources": {
"files": [
"/assets/**"
]
}
}]
}
编辑 2:
如果我 运行 使用本地应用程序 "http-server" 它可以工作,但是当我将文件复制到我的 apache 时它没有检测到更新。在网络选项卡中,我可以看到间隔有效,应用程序每 3 秒从服务器获取一个新的 "ngsw.json"。如果我更新我的应用程序,我可以看到 "ngsw.json" 的响应中有新的哈希值。之后浏览器从我的服务器加载新的 "index.html" 和 "main.***.js" 但应用程序不应用新版本。根据我的代码,它应该显示 "update found" 但什么也没有发生。
您可能需要告诉服务人员检查服务器是否有更新,我通常为此使用服务:
export class UpdateService {
constructor(public updates: SwUpdate) {
if (updates.isEnabled) {
interval(6 * 60 * 60).subscribe(() => updates.checkForUpdate()
.then(() => console.log('checking for updates')));
}
}
public checkForUpdates(): void {
this.updates.available.subscribe(event => this.promptUser());
}
private promptUser(): void {
console.log('updating to new version');
this.updates.activateUpdate().then(() => document.location.reload());
}
在你的app-component.ts
中:
constructor(private sw: UpdateService) {
// check the service worker for updates
this.sw.checkForUpdates();
}
无论出于何种原因,Angular 有时无法正确注册 service worker。所以你可以修改 `main.ts` :
替换:
platformBrowserDynamic().bootstrapModule(AppModule);
与:
platformBrowserDynamic().bootstrapModule(AppModule).then(() => {
if ('serviceWorker' in navigator && environment.production) {
navigator.serviceWorker.register('ngsw-worker.js');
}
}).catch(err => console.log(err));
更改您的应用程序需要使用此方法 activateUpdate(
import { SwUpdate } from '@angular/service-worker';
export class AppComponent implements OnInit {
constructor(private swUpdate: SwUpdate) { }
ngOninit() {
this.swUpdate.available.subscribe(event => {
console.log('A newer version is now available. Refresh the page now to update the cache');
});
this.swUpdate.checkForUpdate()
}
}
检查这个 Link:https://angular.io/guide/service-worker-getting-started
在堆栈上的所有其他解决方案都不起作用后,我开始调试 angular 的 ngsw-worker.js 脚本。我跟踪了更新逻辑并以 "PrefetchAssetGroup" 方法结束。每次调用方法时我都插入了日志记录,然后我意识到它一直在尝试缓存我的 favicon.ico。 我检查了 favicon.ico 在我的 ngsw.json 中的位置,发现网站图标不在那里。一旦我将图标放在该位置,一切就开始正常工作了。
这对我来说适用于所有设备mac/windows/ios/android
export class PwaUpdateService {
updateSubscription;
constructor(public updates: SwUpdate) {
}
public checkForUpdates(): void {
this.updateSubscription = this.updates.available.subscribe(event => this.promptUser());
if (this.updates.isEnabled) {
// Required to enable updates on Windows and ios.
this.updates.activateUpdate();
interval(60 * 60 * 1000).subscribe(() => {
this.updates.checkForUpdate().then(() => {
// console.log('checking for updates');
});
});
}
// Important: on Safari (ios) Heroku doesn't auto redirect links to their https which allows the installation of the pwa like usual
// but it deactivates the swUpdate. So make sure to open your pwa on safari like so: https://example.com then (install/add to home)
}
promptUser(): void {
this.updates.activateUpdate().then(() => {
window.location.reload();
});
}
}
要检查 Angular 的更新版本是否可用,您可以从任何组件调用以下方法,或者只需复制 app.component
.[=13= 中的 IsNewerVersionAvailable
方法]
export class DataService {
constructor(private http: HttpClient, private swUpdate: SwUpdate) { }
private available: boolean = false;
IsNewerVersionAvailable() {
if (this.swUpdate.isEnabled) {
this.swUpdate.available.subscribe(() => {
this.available = true;
});
console.log(this.available);
}
return this.available;
}
}
我在 angular 文档中找到了以下信息: https://angular.io/guide/service-worker-devops#debugging-the-angular-service-worker
总结: angular 站点上有一个有用的端点可以显示 service worker 状态:
http://site-url/ngsw/state
将 /ngsw/state
附加到您的站点地址。如果服务有问题,它应该在那里显示。