2016-03-03 65 views
9

我試圖在測試頁面中實現Service Worker。我的最終目標是脫機運行的應用程序。文件夾結構如下瞭解服務人員範圍

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

我註冊,如下圖所示(內service-worker.js)服務工作者:

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

並在控制檯中我看到

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

如果我頁面位於https://example.com/practice/foopage,我是否需要確保我的service worker範圍是https://example.com/practice/foopage

如果我嘗試在register函數調用像

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

定義的範圍,我得到了錯誤

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. 

的問題是:究竟是什麼範圍指什麼? service worker最終將控制哪些網址的集合?我需要在其他地方移動service-workers.js嗎?如果是這樣,在哪裏?

回答

12

服務人員基本上是您的Web應用程序和互聯網之間的代理,所以如果需要的話,它可以攔截到網絡的呼叫。

本例中的範圍是指服務工作人員能夠攔截網絡呼叫的路徑。可以使用scope屬性明確定義它將覆蓋的範圍。但是:

服務工作人員只能攔截源自服務工作者腳本所在的當前目錄範圍內的請求及其子目錄。 Or as MDN states

服務人員只會在服務人員的範圍內接收來自客戶端的請求。

服務人員的最大範圍是工作人員的位置。

正如你服務人員位於/static/mod/practice/,它不允許其範圍設置爲/practice/foopage/。請求其他主機,例如在任何情況下都可以攔截。

確保服務人員可以攔截所需的所有呼叫的最簡單方法是將其放置在Web應用程序的根目錄(/)中。您還可以使用http標頭覆蓋默認限制並手動設置示波器(請參閱Ashraf Sabry的答案)。

+2

我沒想到在根目錄下的'js'文件是有史以來東西會做。但是,隨着新概念的出現,我猜想新的範例 –

+1

我認爲這主要是出於安全原因。例如,如果你只能訪問'/ static',但不能訪問根目錄('/'),你的服務工作者就不應該攔截到根的請求。 – nils

+9

這只是部分正確 - 範圍決定哪些頁面由服務工作人員控制。一旦頁面由服務工作人員控制,所有* HTTP請求源於該頁面,而不管請求URL如何,都將觸發服務工作人員的「獲取」事件。因此,如果受控頁面爲'https:// thirdpartyapi.com/api/test'發出AJAX請求,則您的服務工作人員將有機會截取該請求。 –

2

留在任何目錄中搜索項目結構帶來的服務人員文件和scope選項設置爲/Service-Worker-Allowed HTTP標頭添加到您的服務人員文件的響應。

我使用的是IIS,所以我會在下面添加到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> 

和註冊工作人員通過:

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); 
     }); 

測試在Firefox和Chrome。

參考例子Service worker specification