iOS17でpwaが開けない不具合の対応
FetchEvent.respondWith received an error
原因
iOS17のアップデート後、突然PWAが開けなくなりました。
pwa上でサイトを開こうとすると白い画面で以下のエラーメッセージが。。。
Safari can’t open the page.
The error was:
“FetchEvent.respondWith received an error: TypeError: Internal error.”
原因を探してみると、iOS17のCacheAPIの不具合に加え、Angularのサービスワーカーでキャッシュ取得の間にエラーハンドリングのロジックが不在していることが分かりました。
Angularのgithubレポジトリでは既に関連イッシューが報告されてました。キャッシュ取得にエラーが発生してもサイトを表示するように@angular/service-worker@16.2.7
バージョンにアップデートができたそうです。
参考:
対応
最新のAngularバージョンを使っている方ならサービスワーカーを16.2.7バージョンにアップデートすれば解除できると思います。ただ、私の場合はangular12を使ってましたので、パッケージをアップデートする代わりに以下の方法を適用しました。
-
ngsw-worker-workaround.js
ファイルの生成 -
node_modules/@angular/service-worker/ngsw-worker.js
の内容をコピしてngsw-worker-workaround.js
に貼り付け - 以下のコードブラックをtry-catch文に書き換える
(Angularのバージョンによって内容は少しずつ違いますので、バージョンに合わせて修正してください。)
const cachedResponse = yield cache.match(req, this.config.cacheQueryOptions);
let cachedResponse;
try {
// Safari 16.4/17 is known to sometimes throw an unexpected internal error on cache access
// This try/catch is here as a workaround to prevent a failure of the handleFetch
// as the Driver falls back to safeFetch on critical errors.
cachedResponse = yield cache.match(req, this.config.cacheQueryOptions);
} catch (error) {
throw new SwCriticalError(`Cache is throwing while looking for a match: ${error}`);
}
-
package.json
のスクリプトにポストビルドを追加
{
"scripts": {
...
"postbuild": "cp ngsw-worker-workaround.js ./dist/ngsw-worker.js",
"build": "ng build && npm run postbuild",
...
},
}
上記の順番により、ビルド後、エラーハンドリングができるサービスワーカーが登録されます。
Cache API operation failed: Internal error
原因
上記の対応でpwaのサイトが開けないエラーは解決できましたが、キャッシュ取得には相変わらず問題が残っています。根本的な問題はiOS17のCacheAPIのため、サービスワーカーのキャシング戦略が活用できなくなります。こちらはiOSで対応を待つしかないですね。
対応
Appleでアップデートパッチをしてくれるまで、iOS17はサービスワーカーを登録しないようにしました。
iOS17のuserAgentにはOSバージョンが記載されてますので、その情報を使います。
- iOS 17 Safari:
Mozilla/5.0 (iPhone; CPU iPhone OS 17_0_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1
- iOS 17 Chrome:
Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) CriOS/117.0.5938.117 Mobile/15E148 Safari/604.1
@NgModule({
imports: [
ServiceWorkerModule.register('ngsw-worker.js', {
enabled: !isDevMode() && !window.navigator.userAgent.includes('iPhone OS 17'),
registrationStrategy: 'registerWhenStable:30000'
}),
]
})
まとめ
iOS17のアップデートにより、CacheAPI仕様が変化されたようです。
Angularサービスワーカーを使っている方、pwaを活用している方は今回の不具合により、色々影響があると思います。
白い画面でエラー文句が表示される現状はngsw-worker.jsの内容をアップデートすることで解除できますが、CacheAPI自体はまだiOSの方で対応前なので、当分の間はiOS17に限ってサービスワーカーのキャッシングは停止した方が良いかもしれません。
Discussion