2016-03-03 28 views
9

Sto tentando di implementare uno Service Worker in una pagina di test. Il mio obiettivo finale è un'applicazione che funziona offline. La struttura della cartella è inferioreInformazioni sull'argomento Service Worker

/myApp 
    ... 
    /static 
    /mod 
     /practice 
     service-worker.js 
     worker-directives.js 
     foopage.js 
    /templates 
    /practice 
     foopage.html 

sto registrando un operaio di servizio, come illustrato di seguito (entro service-worker.js):

navigator.serviceWorker.register('../static/mod/practice/service-worker.js').then(function(reg) { 
    console.log('Registration succeeded. Scope is ' + reg.scope); 
    ... 
} 

e nella console vedo

Registration succeeded. Scope is https://example.com/static/mod/practice/

Se il mio pagina si trova a https://example.com/practice/foopage, è necessario assicurarsi che il mio ambito service worker sia https://example.com/practice/foopage?

Se cerco di definire il campo di applicazione nella chiamata di funzione come register

navigator.serviceWorker.register('../static/mod/practice/service-worker.js', { scope: '/practice/foopage/' }).then(function(reg) { 
    ... 
} 

ottengo l'errore

Registration failed with SecurityError: Failed to register a ServiceWorker: The path of the provided scope ('/practice/foopage/') is not under the max scope allowed ('/static/mod/practice/'). Adjust the scope, move the Service Worker script, or use the Service-Worker-Allowed HTTP header to allow the scope. 

La domanda è: Che cosa significa esattamenteportata riferisce? È la raccolta di URL che il service worker alla fine controllerà? Devo spostare service-workers.js da qualche altra parte? Se sì, dove?

risposta

12

Gli addetti all'assistenza sono fondamentalmente un proxy tra l'applicazione Web e Internet, quindi possono intercettare le chiamate sulla rete se lo si desidera.

L'ambito in questo caso si riferisce al percorso che il gestore del servizio sarà in grado di intercettare le chiamate di rete. La proprietà scope può essere utilizzata in modo esplicito per definire l'ambito che coprirà. Tuttavia:

Gli addetti all'assistenza possono intercettare solo le richieste originate nell'ambito della directory corrente in cui si trova lo script di lavoro del servizio e le relative sottodirectory. Or as MDN states:

L'addetto al servizio cattura solo le richieste dei client nell'ambito dell'operatore del servizio.

La portata massima per un operatore del servizio è la posizione del lavoratore.

Come operaio di servizio si trova in /static/mod/practice/, non è permesso di impostare il campo di applicazione /practice/foopage/. Richieste ad altri host, ad es. https://stackoverflow.com/foo, può essere intercettato in ogni caso.

Il modo più semplice per garantire che il proprio operatore di servizio possa intercettare tutte le chiamate necessarie, è di inserirlo nella directory principale della propria app Web (/). È inoltre possibile ignorare le restrizioni predefinite utilizzando un'intestazione http e impostando manualmente l'ambito (vedere la risposta di Ashraf Sabry).

+2

Non pensavo che un file 'js' nella directory radice era sempre qualcosa che sarebbe stato fatto. Ma con nuovi concetti arrivano nuovi paradigmi, immagino che –

+1

penso che sia principalmente per ragioni di sicurezza. Se si ha accesso solo a '/ static', ma non alla root ('/'), ad esempio, il proprio service worker non dovrebbe essere in grado di intercettare le richieste alla root. – nils

+9

Questo è solo parzialmente corretto: l'ambito determina quali pagine sono controllate dall'operatore del servizio. Una volta che una pagina è controllata da un operatore del servizio, * tutte * le richieste HTTP provenienti dalla pagina, indipendentemente dall'URL della richiesta, attiveranno l'evento 'fetch' dell'operatore del servizio. Quindi, se una pagina controllata fa una richiesta AJAX per 'https: // thirdpartyapi.com/api/test', il lavoratore di servizio avrà la possibilità di intercettarlo. –

2

lasciare il file operaio di servizio in qualsiasi directory imposto dal vostro struttura del progetto e impostare l'opzione scope per / e aggiungere l'intestazione Service-Worker-Allowed HTTP alla risposta del file operaio di servizio.

sto usando IIS, quindi vorrei aggiungere quanto segue al file web.config:

<location path="static/mod/practice/service-worker.js"> 
    <system.webServer> 
     <httpProtocol> 
      <customHeaders> 
       <add name="Service-Worker-Allowed" value="/" /> 
      </customHeaders> 
     </httpProtocol> 
    </system.webServer> 
</location> 

E registrare i lavoratori da:

navigator.serviceWorker.register('/static/mod/practice/service-worker.js', { scope: '/' }) 
     .then(function (registration) 
     { 
      console.log('Service worker registered successfully'); 
     }).catch(function (e) 
     { 
      console.error('Error during service worker registration:', e); 
     }); 

provata su Firefox e Chrome.

riferimento agli esempi in Service worker specification