Options for testing service workers via HTTP

92,527

Solution 1

In general, you need to serve both your page and your service worker script via HTTPS in order to use service workers. The rationale is described at Prefer Secure Origins For Powerful New Features.

There's an exception to the HTTPS requirement in place to facilitate local development: if you access your page and service worker script via http://localhost[:port], or via http://127.x.y.z[:port], then service workers should be enabled without any further actions.

In recent versions of Chrome, you can work around this requirement duriing local development via chrome://flags/#unsafely-treat-insecure-origin-as-secure, as explained in this answer.

Firefox offers similar functionality, via the devtools.serviceWorkers.testing.enabled setting.

Please note that this functionality is only meant to facilitate testing that wouldn't otherwise be able to take place, and you should always plan on using HTTPS when serving the production version of your site. Don't ask real users to go through the steps of enabling those flags!

Solution 2

If you want to debug a plugged-in mobile device's service worker for a real behavior testing of a progressive web app, the ssl chrome start options do not help and you definitely do not need to buy certificates.

@chris-ruppel mentioned installing proxy software, but there is actually an easier way using port forwarding:

Assuming you connect and debug your device using Chrome:

  • In the Chrome Dev Tools "Remote devices" open "Settings" and add a "Port forwarding" rule.
  • If your localhost setup is running on localhost:80,
  • just add a rule "Device port 8080" (can be any unpriviliged port > 1024)
  • and local address "localhost:80" (or mytestserver.sometestdomainwithoutssl.company:8181 or whatever)

After you did that, you can call the URL "http://localhost:8080" on your mobile device and it will be answered by the "localhost:80" on your actual PC/test server. Works perfectly with service workers as if it were your local machine running on your mobile.

Works also for multiple port forwardings and different target domains as long as you remember to use unprivileged ports on your mobile device. See screenshot: See screenshot for some configured ports which will call the PC when called on the mobile

Source of this info is the google remote devices documentation: https://developers.google.com/web/tools/chrome-devtools/remote-debugging/local-server (but as of Apr 2017 it is not very clear to read this simple answer out of it)

Solution 3

I often want to debug and test on a real device. One method I've come up with involves routing the phone's network traffic through Charles Proxy during local development. Unlike all the Chrome-specific solutions, this works with any browser on your phone.

  1. Run Charles on my laptop (which also serves my website with the Service Worker). Once Charles is running, note the IP/port for Step 2.
  2. Configure the mobile device to use my laptop as a proxy.
    • For Android just tap and hold on your WiFi in settings > Modify network > Advanced Settings > Proxy. Use Manual to set the IP/port.
    • For iOS click the (i) icon > HTTP Proxy section. Select Manual, then set the IP/port.
  3. Visiting localhost on my mobile device now allows the Service Worker to be registered and tested.

Solution 4

The easiest way to test pwa, in my case, was using ngrok. https://ngrok.com/download log in, get ur token and set it!

When you run ./ngrok http {your server port} make sure that you use https which will be shown in the terminal after you run this command above.


You could use https://surge.sh too, it is for host a static webpage, if you visit here: https://surge.sh/help/securing-your-custom-domain-with-ssl will be able to see how to set up a ssl certificate

Solution 5

I used ngrok to tunnel the local IP (it is really not that because it is on Google Colab) to a public one.

Going to the ngrok console I can see all the tunnels created. I created just one tunnel for localhost:port but here there are 2, one for HTTP and other for HTTPS (isn't that nice?).

https://i.imgur.com/4v01j7k.png

If I go to the https address of my Web App, on the console I see https://i.imgur.com/5KKak9Y.png

But if I go to the http address, on the console I get https://i.imgur.com/4oFUK1n.png


Q: Can you work with service workers that need HTTPs through tunnels to a remote machine?

A: Apparently yes!


The code behind that registration is (important to know where it fails):

// Here we register the SERVICE WORKER
IndexController.prototype._registerServiceWorker = function() { 

    console.log("1.Starting SW function."); 

    if (!navigator.serviceWorker) { 
        console.log("2.Browser is NOT compatible with SW or something is not working."); 
        return; } 

    console.log("2.Browser is compatible with SW.");

    navigator.serviceWorker.register('/sw.js').then(function() {
        console.log('3.Registration worked!');
    }).catch(function() {
        console.log('3.Registration failed!');
    });
};

And to make it more complicated, my web App using Service Workers is running inside Colab (Google Colab). The web App is running on Node.js inside Colab.

If you are working from localhost it should be easier for you, because the https requirement is not enforced when connecting to localhost (according to theory). [A] and [B]

https://i.imgur.com/wAAZQFU.png

That is not the same that the browser will be nice with your App just because it runs on localhost.


Note: My experiment above..

  • Firefox: worked with and without the settings below.
  • Chrome: Without adding the urls to the whitelist and restartting I got

Going to https web app I got:

IndexController.js:49 Mixed Content: The page at 'https://0a4e1e0095b0.ngrok.io/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://0a4e1e0095b0.ngrok.io/updates?since=1602934673264&'. This request has been blocked; this endpoint must be available over WSS.
IndexController._openSocket @ IndexController.js:49
IndexController @ IndexController.js:10
(anonymous) @ index.js:16
loadScripts @ loadScripts.js:5
46.../utils/loadScripts @ index.js:15
s @ _prelude.js:1
e @ _prelude.js:1
(anonymous) @ _prelude.js:1
IndexController.js:49 Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
    at IndexController._openSocket (https://0a4e1e0095b0.ngrok.io/js/main.js:2251:12)

Going to http web app I got:

Navigated to http://0a4e1e0095b0.ngrok.io/
IndexController.js:17 1.Starting SW function.
IndexController.js:19 2.Browser is NOT compatible with SW or something is not working.

If you are not on localhost AND can't use https, then you may need to change these settings on your browser.


Some people already explained this but here it goes again.

Chrome:

  1. Go to chrome://flags/#unsafely-treat-insecure-origin-as-secure
  2. Add the urls you want to whitelist.
  3. Restart chrome

Note that this will restart all Chrome windows. This is not a solution for me because my tunnels change name every time they are created and I can't be restarting a bunch of windows every time.

https://i.imgur.com/3n4gMoR.png


Firefox / Waterfox

  1. Open Developer Tools
  2. Open settings
  3. Mark "Enable service workers over HTTP (when toolbox is open)"

https://giphy.com/gifs/oA6ZoXqqzdFnxLrZmQ


Firefox/Waterfox You probably don't need to do the changes below, but I did (my browser may be a bit old). More info here.

In about:config

https://i.imgur.com/CjboKnK.png I enabled

dom.serviceWorkers.testing.enabled
dom.serviceWorkers.enabled

I highly recommend looking at this https://developer.mozilla.org/en-US/docs/Web/API/Service_Worker_API/Using_Service_Workers and related pages on that same site.


If someone is interested in the ngrok setup, it is very simple (python version).

#   Install pyngrok python package on your Google Colab Session
!pip install pyngrok

#    Set up your ngrok Authtoken (requires free registration)
!ngrok authtoken YOUR_TOKEN_HERE


#    Invoke ngrok from Python and start tunneling/connecting
from pyngrok import ngrok 

# Open a HTTP tunnel on the default port 80 if not specified
ngrok_tunnel = ngrok.connect('8888')

# You can print it, or go to the ngrok console on https://dashboard.ngrok.com/status/tunnels
print (ngrok_tunnel.public_url)

Share:
92,527
Aman Satija
Author by

Aman Satija

Updated on May 20, 2021

Comments

  • Aman Satija
    Aman Satija almost 3 years

    I want to test service workers but I have a virtual host setup and I can't seem to be able to enable https on localhost.

    How can I whitelist my local virtual host url to test service workers whenever I try and register for the service worker on the localhost? Chrome says https is required to enable service worker. How can I get past this restriction at least for local testing.

  • Aman Satija
    Aman Satija over 8 years
    thanks jeff will try it right away . definately i am using this only for testing.. needed a desperate workaround for time being ...!! i know not ideal practice.. but desprate times call for desprate measure ...!!could you please give me back my hard earned 4 points ...!! i will delete the question if you feel its not appropriate and it will encourage wrong behaviour
  • sp1rs
    sp1rs almost 8 years
    using service worker in localhost, but when it tried to fetch sw.js file from the server it shows net::ERR_INSECURE_RESPONSE ,
  • Phyo Arkar Lwin
    Phyo Arkar Lwin over 7 years
    i am facing that problem too , thanks a lot. To test mobile it is totally impossible , without a proxy. this post need more votes.
  • Jeff Posnick
    Jeff Posnick over 7 years
    Thanks! I've updated the main body to read devtools.serviceWorkers.testing.enabled.
  • Damian Yerrick
    Damian Yerrick over 7 years
    The follow-up question would be one for Software Recommendations: What web servers for iOS and for Android are recommended for testing on a mobile device using the localhost method?
  • Miguel Guardo
    Miguel Guardo over 7 years
    I am using Erlang HTTP Server but any server should work. I used before the 200 HTTP server from Chrome, that you can access from the Google Marketplace.
  • Christopher Lörken
    Christopher Lörken about 7 years
    @chris-ruppel Actually, there is a way to do this without extra proxy software using Chrome Dev Tools inbuild remote devices port forwarding. I've added a detailed answer in this thread.
  • Jackson
    Jackson almost 7 years
    Looks promising but didn't work for me. Just says "This site can't be reached" when trying to visit localhost on Android 5.0.2 after setting up port forwarding.
  • Jackson
    Jackson almost 7 years
    "To test mobile it is totally impossible;" but that's a minor oversight. Let's applaud the people who spec'd service workers...
  • Jackson
    Jackson almost 7 years
    Chris can you elaborate on "1. Run Charles on my laptop"? One can install Charles proxy. He has server running at localhost:8080 on his computer. Then what? You also say "note the IP/port". Where?
  • Romain G
    Romain G almost 7 years
    There is a way to do the same with no Third Party software using chrome's Remote Devices Port Forwarding. See below.
  • Sten Muchow
    Sten Muchow over 6 years
    For anyone who had troubles to find the above - open FF - dev tools - settings cog wheel - advanced settings - enable sw over http. Then you can go to about:debugging#workers in the url or tools - web dev - service workers in the toolbar. Start up the worker!
  • goemic
    goemic over 6 years
    Awesome!! Charles should be installed anyways for mobile development.. Thanks mate!
  • madox2
    madox2 over 6 years
    You saved my day!
  • Machado
    Machado over 6 years
    So you don't need https on localhost? Will SW work fine?
  • Miquel
    Miquel about 6 years
    That should be the accepted answer, it's working fine
  • Mohamed Hussain
    Mohamed Hussain almost 5 years
    @StenMuchow 's answer is working for me in chrome mac and windows
  • Mohamed Hussain
    Mohamed Hussain almost 5 years
    @JeffPosnick what about the android firefox browser, not able to go to about:config and change the setting there? second point is how can we debug the service worker script for mobile firefox, for desktop we could do about:debugging#workers?
  • Marcos R
    Marcos R almost 5 years
    Fast and easy! Don't forget to enable and accept USB Debugging on your phone and plug it to your PC via USB. Thanks man!
  • rwm
    rwm over 4 years
    You can also set the chrome flag using chrome://flags/#unsafely-treat-insecure-origin-as-secure
  • Legends
    Legends over 4 years
    But only for http, if you request resources over https, they won't be cached.
  • Karsten Silz
    Karsten Silz over 4 years
    Does this still work with macOS Catalina and iOS 13.3 in 2020? I followed your instructions to use Charles as a proxy in iOS. Unfortunately, http://localhost:8080 on iOS doesn't connect to my Mac at all. http://local.charles:8080 does (see first FAQ entry), but has no service worker.
  • Chris Ruppel
    Chris Ruppel over 4 years
    @KarstenSilz I'm also seeing failure to connect and would suspect that iOS is the part that is breaking things with regards to localhost. Using iOS 13.3 I was unable to use any iOS browser to connect to localhost (Safari, Brave, Chrome) — visiting a public website was successful and the origins appeared in my Charles logs, indicating that the proxy is being used.
  • Karsten Silz
    Karsten Silz over 4 years
    Worked like a charm! Thank you for the great recommendation!
  • Karsten Silz
    Karsten Silz over 4 years
    @ChrisRuppel I switched to ngrok.com: Free, creates a public HTTPS site for my local app, and works like a charm! The first run took a while until it connected. Only thing I recommend is to switch regions if you're not in the US (ngrok.com/docs#config-options, "regions" parameter).
  • Avner Moshkovitz
    Avner Moshkovitz almost 4 years
    I set up port forwarding, but still getting insecure padlock warning. I filed my steps here
  • Avner Moshkovitz
    Avner Moshkovitz almost 4 years
    I set up proxy, but still getting insecure padlock warning. I filed my steps here
  • Max Coplan
    Max Coplan almost 4 years
    @rwm is there a setting like that but only for specific origins? Want to test some SWs on my local network without letting anything out in the wild be treated as secure
  • Cj Oyales
    Cj Oyales over 3 years
    this helps too, although im having trouble on generating a report using lighthouse
  • Frank
    Frank over 2 years
    Hi @JeffPosnick, thanks for the above solution however I would need some more assistance. I get this new error An SSL certificate error occurred when fetching the script. when I followed the above steps. Can someone help me with a workaround?