Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How exactly add "Service-Worker-Allowed" to register service worker scope in upper folder

There are similar questions about it, but it's not very clear how to apply the solution, and keep to receive an error.

I explain. I'd like to create a simply html/js app using service worker technology. I have:

  • Index.html
  • js/app.js
  • js/sw.js

in app.js the code is (see //*** comments to clearify):

// *** I receive always the error:
// *** ERROR: The path of the provided scope ('/') is not under the max scope allowed ('/js/').
// *** Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope.

var headers = new Headers();
// *** I set the header in order to solve the error above:
// *** The value is set to "/" because this js is included in html file in upper folder.
// *** I tried even "../" and many more others values...
headers.append('Service-Worker-Allowed', '/');
console.log(headers.get('Service-Worker-Allowed'));

if ('serviceWorker' in navigator) {
    console.log('Start trying Registrating Scope');
    // *** I register the service worker.
    // *** The path of service worker is "js/sw.js" because this js is included in html file in upper folder.
    // *** The path of scope is "../" because is the path used by service worker, and I want it uses upper folder scope.
    navigator.serviceWorker.register('js/sw.js', {scope: '../'})
    .then(function(reg) {
        // registration worked
        console.log('Registration succeeded. Scope is ' + reg.scope);
    })
    .catch(function(error) {
        // registration failed
        console.log('Registration failed with ' + error);
    });
    console.log('End trying Registrating Scope');
}

As you see in the comment I still get the error "The path of the provided scope ('/') is not under the max scope allowed ('/js/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope."

Maybe I could move the sw.js file, but I'd like to know what's wrong. Sure the problem is in how to register the header in the first 3 not commented lines of code.

Any advice of the code on how exactly register it?

EDIT:

What I'm missing is that what is to set is the request header, the header sent with the request, before asking the html page... I'm creating headers, useful eventually for a future new request. So js maybe is not the right place to put setting... The setting must be setted before the request to index.html is made, because what's setted in the html or js is setted for the response, or prepared for other requests

now...

My approach now is to call another html page (register.html), in this page I'm tryng to $.ajax() the index.html page, with the right header setted: (I now it could be done with pure js, but for time saving I copy/pasted some already tested code)

 $(document).ready(function(){
        $.ajax({
            type: "GET",
            beforeSend: function(request) {
                request.setRequestHeader("Service-Worker-Allowed", "/");
            },
            url: "index.html",
            complete: function () {
                window.location = "index.html";
            }
        });
    });

I was hoping the first time hit on ajax call I could register the service worker, then redirecting on complete on index.html, I could find it already registered, but event this doesn't work...

I repeat, quickest way is to move sw.js in upper folder. But it's interesting to know how to take control of how to register the service worker, despite of its position in tree folder application...

other advices...?

like image 928
Falco Avatar asked Mar 03 '18 13:03

Falco


1 Answers

Ok... I was a little confused, and even now I guess I have to get deep in the facts and study http headers better...

Anyway as stated in many questions & answer on stackoverflow, it's not possible to alter headers during http request, unless it's not an ajax request (and that's not this case).

now on this post Understanding Service Worker scope for a similar question @Ashraf Sabry answered he could alter the headers using web.config file of IIS Web Server. --> So finally I understood that the header to add is a response header, but before the response is interpreted by the browser --> As stated here https://docs.microsoft.com/en-us/iis/configuration/system.webserver/httpprotocol/customheaders/ that configuration is for response header.

I guess there is not clear way to control that header to make service worker doing his work in a subfolder using html/javascript... It's a problem that could be solved only with server configurations.

A was doing my tests on Node, for didactical porpouse I tried to write a simple http server to test this issue starting from this tutorial https://ilovecoding.org/lessons/create-a-simple-http-server-with-nodejs

the result is here (a "server.js" file runned on Node):

var http = require('http');
var url = require('url');
var querystring = require('querystring');
var fs = require('fs');

http.createServer(function(request, response){
    pathName = url.parse(request.url).pathname;
    console.log(pathName);
    fs.readFile(__dirname + pathName, function(err, data){
        if(err){
            response.writeHead(404, {'Content-type':'text/plan'});
            response.write('Page Was Not Found');
            response.end();
        }
        else{
            if(pathName.endsWith(".html")){
                //response.writeHead(200, {'Service-Worker-Allowed':'/', 'Content-Type':'text/html'});
                response.writeHead(200, {'Content-Type':'text/html'});
                console.log("serving html");
            }
            else if(pathName.endsWith(".js")){
                response.writeHead(200, {'Service-Worker-Allowed':'/', 'Content-Type':'application/javascript'});
                //response.writeHead(200, {'Content-Type':'text/javascript'});
                console.log("serving js");
            }
            else if(pathName.endsWith(".css")){
                //response.writeHead(200, {'Service-Worker-Allowed':'/', 'Content-Type':'text/css'});
                response.writeHead(200, {'Content-Type':'text/css'});
                console.log("serving css");
            }
            else{
                response.writeHead(200);
                console.log("serving other");
            }
            response.write(data);
            response.end();
        }
    })
}).listen(8080);

Using this js Node Server I could reach the same result stated for settings in IIS in the above link.

Note that after some test with this js, I reached that the file which needs "Service-Worker-Allowed:/" is the app.js file.

Now the application work as wanted returning no error. As final prove tracing requests on fiddler I can clearly see the initial request for app.js, with "Service-Worker-Allowed: /" in the response;

My conclusion is that not always it is possible to handle server configuration, so putting service worker file on root folder of the app is the best approach.

Hope this could be helpful for some others...

like image 54
Falco Avatar answered Sep 19 '22 13:09

Falco