私はGoogle Web Starter Kit( https://github.com/google/web-starter-kit )で遊んでいて、少しプログレッシブWebアプリが機能しているのに1つのことにこだわっています:外部CDNからの静的ファイルのキャッシュ。例えば。 https://fonts.googleapis.com/icon?family=Material+Icons のMDLアイコンを使用しています。ServiceWorkerはURLにのみ応答するため、リクエストをキャッシュする方法がわかりませんアプリドメイン内。
表示されるオプション:1.ファイルをダウンロードし、ベンダーフォルダーに配置します。利点:SWキャッシュを簡単に設定できます。短所:新しいアイコンが追加されても、ファイルは最新の状態に保たれません(ただし、コードでは使用可能なアイコンのみを使用するため、実際には問題になりません)。
NPMリポジトリを使用: https://www.npmjs.com/package/material-design-icons とビルドステップを使用して、node_modulesからCSSファイルをコピーします。利点:NPMからの自動更新が可能になります。短所:設定が少し複雑。
SWを使用して外部URLをキャッシュできる、いくつかの豪華なプロキシメソッド。例えばmyapp.com/loadExternal?url= https://fonts.googleapis.com/icon?family=Material+Icons
今は2に傾いていますが、3が可能かどうかを知るのはクールです。
sw-toolbox docs を読んで、その方法を理解しました。これを私の実行時キャッシングに追加する必要がありました:
// cache fonts hosted on google CDN
global.toolbox.router.get(/googleapis/, global.toolbox.fastest);
TLDR:オプション3を試してください。後で感謝します。
Google Docs から:
CORSをサポートしていない場合、デフォルトでは、サードパーティのURLからのリソースの取得は失敗します。 no-CORS
これを克服するためのリクエストのオプションですが、これにより「不透明な」応答が発生します。これは、応答が成功したかどうかを判断できないことを意味します。
そう
オプション1
追加 no-cors
ヘッダー
var CACHE_NAME = 'my-site-cache-v1';
var urlsToPrefetch = [
'/',
'/styles/main.css',
'/script/main.js',
'https://fonts.googleapis.com/icon?family=Material+Icons'
];
self.addEventListener('install', function(event) {
// Perform install steps
event.waitUntil(
caches.open(CACHE_NAME)
.then(function(cache) {
console.log('Opened cache');
// Magic is here. Look the mode: 'no-cors' part.
cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {
return new Request(urlToPrefetch, { mode: 'no-cors' });
})).then(function() {
console.log('All resources have been fetched and cached.');
});
})
);
});
OPが言ったように、リソースが更新されると、このシナリオでは最新のコピーを取得するのは困難です。もう1つの問題は、先ほど述べたように、応答が成功したかどうかはわかりません。
オプション2
またはOPが言ったように、プロキシサーバーを作成できます:(Pseudocode、not not test、Node Express code)
var request = require('request');
app.get('/library', function(req,res) {
// read the param
var thirdPartyUrl = req.query.thirdPartyUrl;
request(thirdPartyUrl).pipe(res);
});
そして、あなたが行くとき/library?thirdPartyUrl=https://fonts.googleapis.com/icon?family=Material+Icons
は応答を提供し、通常は応答をキャッシュする方法でキャッシュする必要があります。例:削除no-cors
&urlsToPrefetch
を以下の値に置き換えます:
var urlsToPrefetch = [
'/',
'/library?thirdPartyUrl=https://fonts.googleapis.com/icon?family=Material+Icons',
'/library?thirdPartyUrl=https://fonts.googleapis.com/icon?family=Roboto'
];
オプション3
これが最良で簡単な方法だと思います。ワークボックスを使用します。ワークボックスの有無にかかわらずPWAを作成しようとしましたが、ワークボックスの使用は簡単でした。
ワークボックスについて読む: https://developers.google.com/web/tools/workbox/
初期設定後にこのようなルートを実装します。
workbox.routing.registerRoute(
new RegExp('^https://third-party.example.com/images/'),
new workbox.strategies.CacheFirst({
cacheName: 'image-cache',
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200],
})
]
})
);
Service Workerはアプリドメイン内のURLにのみ応答するため、リクエストをキャッシュする方法がわかりません。
不正解です。ページをアクティブに制御しているサービスワーカーは、クロスオリジンリソースに対するネットワークリクエストを傍受して応答する機会があります。標準のfetch
イベントが発生し、 event.request.mode
は、によって行われたリクエストのコンテキストに応じて、"cors"
または"no-cors"
になりますページ。
つまり、ページを制御するService Workerがある限り、そのページが同じリソースまたはCross-Originリソースに対してネットワークリクエストを行うと、Service Workerはfetch
に応答できます。イベント。
ずれているかもしれませんが、次のように簡単ですか?
caches.open(version)
.then(function(cache) {
return cache.addAll([
'/',
'index.html',
'/css/app.css',
'/js/app.min.js',
'/assets/images/logo_target_white.png',
'/scripts/angular-jwt.min.js',
'/scripts/ng-file-upload.min.js',
// this guy here
'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'
]);
})
この方法を使用し、chromeツールでアプリのキャッシュを検査すると、適切にキャッシュされているように見えます。