Angular Service Worker SwUpdate.available 未触发

问题描述 投票:0回答:8

我很难将 Angels 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 caching apache2 angular6 progressive-web-apps
8个回答
61
投票

您可能需要告诉服务人员检查服务器是否有更新,我通常使用服务来执行此操作:

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));

9
投票

我在角度文档中找到了以下信息: https://angular.io/guide/service-worker-devops#debugging-the-angular-service-worker

总结: 角度站点上有一个有用的端点,可以显示服务工作者状态:

http://site-url/ngsw/state

/ngsw/state
附加到您的网站地址。如果服务有问题,应该在那里显示。


8
投票

在堆栈上的所有其他解决方案都不起作用之后,我开始调试 Angular 的 ngsw-worker.js 脚本。我跟踪了更新逻辑并最终到达“PrefetchAssetGroup”方法。每次调用方法时我都会插入日志记录,然后我意识到它不断尝试缓存我的 favicon.ico。 我检查了 ngsw.json 中 favicon.ico 的位置,发现 favicon 不在那里。一旦我将图标放在该位置,一切就开始正常工作。


0
投票

对您的应用程序进行更改,您需要使用此方法 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


0
投票

我一直在使用 Michael Doye 接受的答案中的解决方案一段时间,但当我升级到 Angular 14 时它停止工作。

以下解决方案源自Vytautas Pranskunas

的评论

使用 NgZone 在 Angular 之外运行 interval

    constructor(public swUpdate: SwUpdate, private ngZone: NgZone) {

    if (swUpdate.isEnabled) {
      this.ngZone.runOutsideAngular(() =>
        interval(1000 * 10).subscribe(val => {
          swUpdate
            .checkForUpdate()
            .then(_ => console.log('SW Checking for updates'));
        })
      );
    }

(每10秒检查一次以进行测试-增加生产间隔)


0
投票

我写了这个代码来触发新版本也许对你有帮助,

ngOnInit(): void {
    this.updates.versionUpdates
      .pipe(
        filter((evt): evt is VersionReadyEvent => evt.type === 'VERSION_READY'),
        switchMap(() =>
          this.snackBar
            .open('New version available', 'Update now')
            .afterDismissed()
        ),
        filter((result) => result.dismissedByAction),
        map(() => this.updates.activateUpdate().then(() => location.reload()))
      )
      .subscribe();
  }

-1
投票

这对我在所有设备 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();
        });
    }
}

-4
投票

要检查是否有较新版本的 Angular 可用,您可以从任何组件调用以下方法,或者只需复制

IsNewerVersionAvailable
中的
app.component
方法。

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;
    }    
}
© www.soinside.com 2019 - 2024. All rights reserved.