簡體   English   中英

如何使用單個Javascript標記安裝服務工作者和清單?

[英]How do I install both a service worker and a manifest with a single Javascript tag?

我已經為網站構建了一項服務,可以輕松地將推送通知集成到他們的網站中,但是當前的Chrome實施還需要他們設置清單和服務工作者。

有沒有辦法只用一行Javascript來設置服務工作者和清單?

是的,您可以減少讓他們在其源上托管服務工作文件的步驟,並在其頁面中包含一行Javascript。

您可以使用它們包含的Javascript來執行此操作:

  1. 注冊服務工作者
  2. 將一個不存在的清單的鏈接注入頭部
  3. 與服務工作者一起攔截對該清單的請求,並使用您的自定義清單進行響應

你的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);
    }
});

請注意我已經避免添加清單標記(如果已存在)。

您的服務人員應該看起來像:

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.');
}

請注意它如何僅攔截清單請求,並檢查是否存在實際清單。 如果是這樣,服務工作者只需將我們的自定義字段附加到它。 如果清單尚不存在,我們將自定義字段作為整個清單返回。

更新(2015年8月25日):我剛剛讀到Request.context已被棄用,所以不幸的是,您需要找到一種新的方法來發現請求是否是清單或其他代替行的內容if (e.request.context === 'manifest')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM