google chrome - How do I install both a service worker and a manifest with a single Javascript tag? -
i've built service websites integrate push notifications site current chrome implementation requires set manifest , service worker.
is there way set service worker , manifest single line of javascript?
yes can reduce steps getting them host service worker file on origin , include single line of javascript in page.
you can using javascript include to:
- register service worker
- inject link non-existent manifest head
- intercept request manifest service worker , respond custom manifest
your javascript should this:
navigator.serviceworker.register('sw.js').then(function(registration) { console.log('serviceworker registration successful scope: ', registration.scope); var head = document.head; var nomanifest = true; // walk through head check if manifest exists (var = 0; < head.childnodes.length; i++) { if (head.childnodes[i].rel === 'manifest') { nomanifest = false; break; } } // if there no manifest already, add one. if (nomanifest) { var manifest = document.createelement('link'); manifest.rel = 'manifest'; manifest.href = 'manifest.json'; document.head.appendchild(manifest); } }); note how i've avoided adding manifest tag if 1 exists.
your service worker should like:
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) { // found real manifest, should 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 custom field pre-existing manifest'); resolve(new response(blob)); }); } else { // there no manifest return ours console.log('injected custom manifest'); resolve(new response('{ "custom_field": "hello world" }')); } }); })); } }); // these pieces cause service worker claim client when registered instead of waiting until next load. means approach can work when user lands on site. if (typeof self.skipwaiting === 'function') { console.log('self.skipwaiting() 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() not supported.'); } if (self.clients && (typeof self.clients.claim === 'function')) { console.log('self.clients.claim() 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() not supported.'); } note how intercepts requests manifests, , checks if 1 exists. if does, service worker appends our custom fields it. if manifest doesn't exist return our custom field whole manifest.
update (august 25th 2015): read request.context has been deprecated unfortunately need find new way of discovering whether request manifest or else in place of line if (e.request.context === 'manifest').
Comments
Post a Comment