How Do I Make a Service Worker Compatible with Wildcard Subdomains? - javascript

I have a fairly simple question. I have a manifest.json file for my new service worker that lists "start_url" as "https://example.com" and the scope is "/". That works great unless the URL has a subdomain. In that case I get several errors saying that the manifest start url is not valid, it has been ignored, and that the manifest has no matching service worker.
The service worker still works but I would like to eliminate these errors. I use wildcard subdomains for all listings categorized by geographic location (ex: https://city-state.example.com). That lets me feather out the categories on the other side of the domain name (ex: https://city-state.example.com/category/subcategory). Is there a way to use something like https://(*).example.com for the start url or scope to avoid this error?

A service worker is scoped to a single origin and no higher in a file page than the level it is served from.
The rules are to provide security and prevent 3rd party scripts from attaching service workers to invade your site.
You will have to replicate your service worker on each origin. But honestly, unless the application is exactly the same you will want to customize the service worker logic to the specific application.

Related

How to separate caches on different pages / for different service workers?

I have two separate applications under the same origin but on different pages (say origin/a/ and origin/b/). Each page registers a service worker, which operates under its own scope. Whilst service workers are restricted to the pages they are registered on, they share the same caches from the origin. And if I want each service worker to clean up its old caches, it turns out it wipes out also the caches created by another service worker.
I ended up defining a scope const in service workers and manually checking if the cache name starts with it. However, this seems a bit fragile since one could rename this scope, and the cache will get lost. Another approach of using self.registration.scope as a cache name part looks better but also cannot guarantee consistent behaviour for nested pages that could contain yet another service worker.
Is there any consistent way to bind a cache to a service worker that I am missing?

consequences of changing a Service Worker directory?

as you might already know, you should put your service workers inside the base directory so that it has the scope of the whole project, otherwise some features (e.g. navigator.serviceWorker.ready()) won't be available.
My problem is that I've initially put my service worker inside a directory and now I feel kinda trapped.
I use the service worker to register and handle web push notifications and I'm wondering if I would lose all my current subscriptions if I move it to the base directory
N.B. It's mandatory that the service worker registered will remain the same, no new service worker should be registered
If you don't want to move your service worker in base directory. You can use "Service-Worker-Allowed" header in your response. If this header is present then your service worker will be registered even if your sw.js file is in nested directory.
Service-Worker-Allowed header '/'
here the the official documentation regarding this header.
https://w3c.github.io/ServiceWorker/#service-worker-allowed

Using Service Worker API in a multi site environment

So with all the new stuff like notifications and offline caching available now with the service worker api I've been looking to add it to my web app.
The only thing is I can't seem to figure out is how to deal with the the https/ssl issue.
My site allows people to host websites in an online no code environment. New sites are accessed by subdomains off the main domain. This by itself I can only see requiring a wildcard subdomain ssl cert.
The complication I'm facing is that premium sites can add their own top level domain. Which will break the service worker as far as I can tell.
All these sites only require the user to sign up once so users are shared between sites and you can also get your notifications and messages cross site.
I would like to take advantage of the notifications part of the api for mobile but I'm going to need to get around this issue first.
Any help or enlightenment on this would be much appreciated :).
As Alex Russel pointed in his article:
Service Worker scripts must be hosted at the same origin
and Service Worker can't work outside its scope. Subdomains are not the same origin, so you'll need specific worker for specific client's page.
However, I can't see a problem here - when someone will enter yourpremiumclient.com, DNS server (ex. cloudflare, which offers free HTTPS and can force HTTPS) will point to your server, where worker could install and control this domain scope. Of course, the same worker won't be able to control your default scope ex. yourclient.yourdomain.com.

How do I load a Web Worker script over HTTPS?

I am attempting to use a Web Worker to offload some CPU intensive calculations into a separate thread. For a little context, I am taking an audio stream from getUserMedia and saving it into a file to be uploaded to my service after it is complete. I am able to retrieve the stream from the user and play it back via the WebAudio API and through an HTML5 player, but now I need to take the next step of saving it into a file.
The problem:
My main service is running over an HTTPS connection, since it is restricted to signed in users only. I have a worker script that does what I need it to, and I am attempting to load the script in via a relative path into my worker. I am receiving the following error
Mixed Content: The page at 'https://someurl.com:1081/some/path' was loaded over HTTPS,
but requested an insecure Worker script
'http://someurl.com/some/path/lib/assets/javascripts/worker.js'.
This request has been blocked; the content must be served over HTTPS.
I figured it was because I was using a relative path in my code like so:
worker = new Worker('lib/assets/javascripts/worker.js');
I wanted to rule this out so I made the following change:
worker = new Worker('https://someurl.com:1081/some/path/lib/assets/javascripts/worker.js');
This did not solve my error. It appears that the Worker is loading my script via HTTP no matter what url location I attempt to use. I couldn't find any reference on how to use the Web Worker via HTTPS, so I am hoping someone can provide some insight.
Possible Solution
I do want you to know there is a possible solution, but it seems a bit hacky to me. I can load my worker script up as a Blob and pass that directly into the Worker. If this is the only solution, I can make it work. But I was hoping to find a way to make the script load via HTTPS.
Have you tried
//someurl.com:1081/some/path/lib/assets/javascripts/worker.js
instead of
https://someurl.com:1081/some/path/lib/assets/javascripts/worker.js
Just something I found here,
Deezer content is served over HTTP
I solved this. The error itself was misleading and caused me to go down a rabbit hole looking for the solution.
The issue here actually stems from the way I have this service configured. The service that starts the web worker is actually proxied behind another service, and all requests go through the parent service. This works great for most requests, but was causing an error in this case. Instead of forwarding the request on this port to my app, the web worker was attempting to download the worker script from the parent service itself. This means the error stemmed from the fact that the script wasn't found, not that the protocol was incorrect.
To solve this, I had to pass in a localized script location from Rails using its asset pipeline. This allowed the worker to grab the script and actually work.

AJAX between a static webpage and google app-engine server sharing same TLD

I have the main website hosted by a reliable static web hosting service. Which only allow me to host static files like html, css, js etc. Now I have few requirements which would need user Login and data storage. I think I can handle this using App Engine Python.
My app is similar to a Voting module, So i will explain it using its example.
My plan is to configure things something like this:
main website: www.example.com
appengine: gae.example.com
On the main website an anonymous user visits: http://www.example.com/vote.html, he should see current voting status (which has been retrieved from app engine). and a login button (from twitter/facebook). when he logins, he should be able to cast his vote and the vote be saved back to the appengine server.
I can handle most of the things but two. (taking same origin policy into account.)
How do I maintain authentication between two domain names. i.e. www.example.com and gae.example.com.
How do I make HTTP POST request to the gae.example.com from www.example.com and use the returned json data.
Note: I want to avoid iframes as much as possible.
You need to use JSONP.
Subdomains actually violate the same origin policy. This is because some hosted solutions provide subdomains for different users. This would allow users to attack each other's sites.
See: Same Origin Policy - AJAX & using Public APIs
You can maintain login between the two sub-domains by making sure that the login cookie is set on the root domain with subdomain access allowed. The sub-domains will be able to access the cookies of the root domain. See https://serverfault.com/questions/153409/can-subdomain-example-com-set-a-cookie-that-can-be-read-by-example-com for some examples.
I don't believe you can make ajax calls directly to another sub-domain. If the target sub-domain is cooperating and supports JSONP, you can do it that way (you end up inserting a script tag with a call to a script and that script calls you back with the data). Because the loading of scripts isn't subject to the same origin policy, you can work around it, but the target sub-domain has to be configured to allow and support JSONP.

Categories

Resources