Angular Service Worker SwUpdate.available 未触发
Posted
技术标签:
【中文标题】Angular Service Worker SwUpdate.available 未触发【英文标题】:Angular Service Worker SwUpdate.available not triggered 【发布时间】:2018-11-30 19:23:28 【问题描述】:我很难将 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”,但应用程序不应用新版本。根据我的代码,它应该说“找到更新”,但什么也没发生。
【问题讨论】:
Angular 文档是最好的资源,请参考this page 【参考方案1】:您可能需要告诉服务人员检查服务器是否有更新,我通常为此使用服务:
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));
【讨论】:
只是我理解 SwUpdate 对...我进入我的应用程序,在任何组件中写“hello world”,ng build --prod 我的应用程序,将它复制到我的 apache2 并且服务工作者应该刷新它...对吗? 对对对,在 yourdomain.com/ngsw/state 上查看debug log,看看任务队列中是否有任何东西 我刚刚完全重置了我的测试系统并设置了一个新的 apache 服务器。在 main.ts 中应用您的修复后,现在一切正常,感谢您的帮助 @BhaumikThakkar 请在此处查看文档:angular.io/guide/… @MichaelDoye 这个解决方案是否仍然有效并推荐用于 Angular V8?我注意到更新后我在 ios 中的 PWA 没有重新加载页面,这意味着它可能没有触发 activateUpdate()【参考方案2】:对您的应用程序进行更改需要此方法 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()
查看此链接:https://angular.io/guide/service-worker-getting-started
【讨论】:
我按照你说的做了(保持一个空标签打开并在进行更改后重新启动 http-server)但服务人员没有更新到新版本,我不得不完全关闭浏览器并再次启动它以获取最新版本。我的 ngsw-config.json 可能有问题吗? 仍然不起作用, SwUpdate.available.subscribe 永远不会被触发,但我不知道为什么。我在其中放了一个 console.log ,但我永远看不到它。如果我构建我的应用程序并将其放置在我的服务器上,服务人员根本不会对其做出反应 很抱歉,您可以在 if 条件中添加 this._swUpdate.checkForUpdate() 我使用的间隔是每 10 秒检查一次更新,但它对新版本没有反应(我更新了我的代码示例) 我不确定是否可以共享整个代码,因为它是一个内部项目。我可以提供哪些文件来提供帮助?【参考方案3】:在堆栈上的所有其他解决方案都不起作用之后,我开始调试 Angular 的 ngsw-worker.js 脚本。我跟踪了更新逻辑并最终使用了“PrefetchAssetGroup”方法。每次调用方法时我都会插入日志记录,然后我意识到它一直在尝试缓存我的 favicon.ico。 我检查了我的 ngsw.json 中 favicon.ico 的位置,并意识到 favicon 不在那里。将图标放在该位置后,一切都开始正常工作了。
【讨论】:
【参考方案4】:这对我在所有设备 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();
);
【讨论】:
【参考方案5】:要检查是否有更新的 Angular 版本可用,您可以从任何组件调用以下方法,或者只需复制 app.component
中的 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;
【讨论】:
【参考方案6】:我在 Angular 文档中找到了以下信息: https://angular.io/guide/service-worker-devops#debugging-the-angular-service-worker
总结: 在 Angular 站点上有一个有用的端点可以显示服务工作线程状态:
http://site-url/ngsw/state
将/ngsw/state
附加到您的网站地址。如果服务有问题,它应该在那里显示。
【讨论】:
以上是关于Angular Service Worker SwUpdate.available 未触发的主要内容,如果未能解决你的问题,请参考以下文章
使用 Angular Service Worker 发送 JWT 令牌
与 Angular.js 控制器通信 service-worker