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 令牌

service worker

与 Angular.js 控制器通信 service-worker

Angular Service Worker 更新多个域

无法在我的 NX 工作区中使用 @angular-service-worker

service worker 消息推送