4

プッシュ通知をサイトに簡単に統合するための Web サイト用のサービスを構築しましたが、現在の Chrome の実装では、マニフェストと Service Worker もセットアップする必要があります。

Javascript の 1 行だけで Service Worker とマニフェストを設定する方法はありますか?

4

1 に答える 1

7

はい、オリジンで Service Worker ファイルをホストする手順を減らし、ページに 1 行の Javascript を含めることができます。

それらに含まれるJavascriptを使用してそれを行うことができます:

  1. サービスワーカーを登録する
  2. 存在しないマニフェストへのリンクを head に挿入する
  3. そのマニフェストへのリクエストを Service Worker でインターセプトし、カスタム マニフェストで応答します

Javascript は次のようになります。

navigator.serviceWorker.register('sw.js').then(function(registration) {
    console.log('ServiceWorker registration successful with scope: ', registration.scope);
    var head = document.head;
    var noManifest = true;
    // Walk through the head to check if a manifest already exists
    for (var i = 0; i < head.childNodes.length; i++) {
        if (head.childNodes[i].rel === 'manifest') {
            noManifest = false;
            break;
        }
    }
    // If there is no manifest already, add one.
    if (noManifest) {
        var manifest = document.createElement('link');
        manifest.rel = 'manifest';
        manifest.href = 'manifest.json';
        document.head.appendChild(manifest);
    }
});

マニフェスト タグが既に存在する場合、マニフェスト タグを追加することをどのように回避したかに注意してください。

Service Worker は次のようになります。

self.addEventListener('fetch', function(e) {
    if (e.request.context === 'manifest') {
        e.respondWith(new Promise(function(resolve, reject) {
            fetch(e.request).then(function(response) {
                if (response.ok) {
                    // We found a real manifest, so we should just add our custom field
                    response.json().then(function(json) {
                        json.custom_field = 'Hello world';
                        var blob = new Blob([JSON.stringify(json)], { type: 'application/json' });
                        console.log('Appended a custom field to the pre-existing manifest');
                        resolve(new Response(blob));
                    });
                } else {
                    // There was no manifest so return ours
                    console.log('Injected a custom manifest');
                    resolve(new Response('{ "custom_field": "Hello world" }'));
                }
            });
        }));
    }
});

// These pieces cause the service worker to claim the client immediately when it is registered instead of waiting until the next load. This means this approach can work immediately when the user lands on your site.
if (typeof self.skipWaiting === 'function') {
    console.log('self.skipWaiting() is supported.');
    self.addEventListener('install', function(e) {
        // See https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#service-worker-global-scope-skipwaiting
        e.waitUntil(self.skipWaiting());
    });
} else {
    console.log('self.skipWaiting() is not supported.');
}

if (self.clients && (typeof self.clients.claim === 'function')) {
    console.log('self.clients.claim() is supported.');
    self.addEventListener('activate', function(e) {
        // See https://slightlyoff.github.io/ServiceWorker/spec/service_worker/index.html#clients-claim-method
        e.waitUntil(self.clients.claim());
    });
} else {
    console.log('self.clients.claim() is not supported.');
}

マニフェストのリクエストのみを傍受し、マニフェストが実際に存在するかどうかを確認する方法に注意してください。その場合、Service Worker はカスタム フィールドを追加するだけです。マニフェストがまだ存在しない場合は、カスタム フィールドをマニフェスト全体として返します。

更新 (2015 年 8 月 25 日): Request.context が非推奨になったことを読んだばかりなので、残念ながら、リクエストがマニフェストに対するものなのか、行の代わりに何か他のものに対するものなのかを発見する新しい方法を見つける必要がありますif (e.request.context === 'manifest')

于 2015-07-07T21:53:33.817 に答える