progressive-web-appsservice-workercapacitor

Capacitor: net::ERR_CONNECTION_REFUSED An unknown error occurred when fetching the script


I have an issue where I load service-worker with capacitor, it has an error net::ERR_CONNECTION_REFUSED and in the console An unknown error occurred when fetching the script.

Full error:

TypeError: Failed to register a ServiceWorker for scope ('https://localhost/') 
with script ('https://localhost/service-worker.js'): 
An unknown error occurred when fetching the script.

Here the script for service worker register:

 <script>
      if ("serviceWorker" in navigator) {
        navigator.serviceWorker
          .register("/service-worker.js")
          .then((registration) => {
            console.log(
              "Service Worker registered with scope:",
              registration.scope
            );
          })
          .catch((error) => {
            console.log("Service Worker registration failed:", error);
          });
      }
    </script>

When I check this on the web browser, it works perfectly but when I run npx cap run android I got the error I mentionned earlier.

Here the result in web browser: enter image description here

And the result from the inspected webview enter image description here

Here the repo: https://github.com/radonirinamaminiaina/capacitor-sw

How can I solve this? Already tried this: PWA + Capacitor.JS: Failed to register a service worker (in Android) but the error change to net::ERR_NAME_RESOLVED

Thank you


Solution

  • By default, capacitor can't access to the service worker which we want to register. So we need to create a bridge and use shouldInterceptRequest so it can handle the request from our webView entrypoint file.

    Here the full solution:

    package com.root.app; // Your package name
    
    import android.os.Bundle;
    import com.getcapacitor.BridgeActivity;
    import android.webkit.ServiceWorkerClient;
    import android.webkit.ServiceWorkerController;
    import android.webkit.WebResourceRequest;
    import android.webkit.WebResourceResponse;
    
    public class MainActivity extends BridgeActivity {
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
          ServiceWorkerController swController = ServiceWorkerController.getInstance();
    
          swController.setServiceWorkerClient(new ServiceWorkerClient() {
            @Override
            public WebResourceResponse shouldInterceptRequest(WebResourceRequest request) {
              if (request.getUrl().toString().contains("index.html")) {
                request.getRequestHeaders().put("Accept", "text/html");
              }
    
              // Access Capacitor's bridge and use its local server to handle the request
              return MainActivity.this.getBridge().getLocalServer().shouldInterceptRequest(request);
            }
          });
        }
      }
    }
    

    After that, when you run npx cap run android, it should work. Here a screenshot from chrome://inspect

    enter image description here