2015-11-19 82 views
9

我有一個服務工作者腳本,在多個站點級別重複註冊。如何防止同一服務人員在多個頁面上註冊?

換句話說,相同的服務人員註冊爲www.site.ca/,www.site.ca/text-text,www.site.ca/example-example,等

網站是建立在PHP與不同的網址生成取決於類似API的內容。服務人員註冊在這些頁面上的原因是因爲大多數網站流量都在這些頁面上,而不是在主頁上。結果是相同的服務人員在不同的頁面上使用不同的ID註冊。

有沒有人有辦法阻止多個子級別的同一個腳本的多次註冊?

編輯:

服務工作者的目的是建立通知,即使用戶沒有在網站上。此外,我遇到的問題會對將來更新服務人員的任何嘗試產生負面影響,因爲會有多個副本需要更新。其結果是,當用戶再次登錄特定頁面時,只有一個副本會更新。不能保證該服務工作者文件的所有副本都會被更新。此外,多個副本的結果導致用戶從站點獲取堆棧通知,因此這是一個問題。

編輯:

下面是我到目前爲止和我的理解範圍定義它得到註冊。然而,問題在於它需要能夠註冊到任何人進入站點,因此範圍設置爲「/」。

我想解決的問題是阻止相同服務工作者文件的後續寄存器。

Localhost是實際站點的佔位符。

navigator.serviceWorker.register('localhost/service-worker.js', {scope: './'}) 
.then(initialiseState); 

在Chrome瀏覽器開發調試工具,所產生的服務人員都是這樣的格式:

範圍:本地主機/ URL /材料/
註冊ID:110
活動的工作:
安裝狀態:激活
運行狀態:已停止
腳本:localhost/service-worker.js
...

範圍:本地主機/
註冊ID:111
活動的工作:
安裝狀態:已激活
運行狀態:停機
腳本:本地主機/服務worker.js
...

範圍:本地主機/ URL
註冊ID:112
活動的工作:
安裝狀態:已激活
運行狀態:停機
腳本:本地主機/服務worker.js
...

理想情況下,我想以某種方式只保留一個條目。

+0

我們應該怎麼知道,沒有看到任何代碼? – PHPglue

+0

@PHPglue沒有包含代碼,因爲認爲這不是必要的,因爲它更像是服務人員的行爲問題。 – KROrb

+0

@PHPglue給問題增加了更多上下文 – KROrb

回答

7

根據MDNServiceWorkerContainer.register方法利用選項的第二個參數:

目前可用的選項爲:

  • 範圍:表示定義了一個服務工人的登記範圍的URL的USVString;服務工作人員可以控制哪些範圍的URL。這通常是一個相對URL,當沒有指定 時,它默認爲'/'。

至於你更新的問題,W3C Service Workers WD說:

當一個 已經存在於用戶代理的同一範圍URL的服務人員註冊會導致現有服務人員 註冊將被替換。

因此navigator.serviceWorker.register(url, {scope: '/'}).then(doSomething)應該工作。

問題是在你的榜樣範圍網址:

./應該/

+0

我的理解是範圍會限制註冊,但在我正在處理的網站上工作不正常。這些網址是根據某些參數生成的,並不總是像/ about或/ contact us這樣的常量。這些網頁都是一種着陸頁,因爲導致網站的最可能的用戶搜索是構成網址的參數。因此,無論用戶在哪裏,服務人員都需要註冊,我的目標是確保服務人員只有一個副本。 – KROrb

+2

服務人員 - 就​​像appcache - 應該鏈接到您的應用程序的所有頁面並註冊。上面的問題確實是指定一個* relative *作用域('。/'),這會強制創建新的服務工作者實例,而不管服務工作者腳本本身是否相同。如果您希望將相同的實例連接到所有頁面,而不考慮路徑,則應該使用絕對/根路徑,例如'/'作爲範圍。 – Flaki

+0

謝謝。這工作! – KROrb

11

在站點與子目錄的情況下,要將所有的子頁面是由同一個頂級服務工作人員控制,我建議使用服務工作人員腳本位置的絕對URL,然後依靠在省略options.scope時發生的默認行爲。

請注意,另一個響應中引用的MDN docs對於默認行爲不正確。服務人員specificationupdated in January 2015,將默認範圍更改爲相當於new URL('./', serviceWorkerScriptUrl).toString()。 (該MDN文檔有since been updated,應該是準確的。)

爲了說明爲什麼我建議在這種使用情況下省略options.scope,請考慮以下方案,假設你想有一個單一的,共享的服務人員註冊:

  • navigator.serviceWorker.register('/sw.js')會給你一個範圍/,這是你想要的註冊。
  • navigator.serviceWorker.register('/sw.js', {scope: '/'})將會給你一個範圍爲/的註冊,這也是你想要的,但是對於你用默認行爲得到的結果沒有任何好處。
  • navigator.serviceWorker.register('/subsite/sw.js', {scope: '/'})將無法​​註冊,因爲對於生活在/subsite/sw.js的服務人員腳本,/的範圍太寬泛。
  • navigator.serviceWorker.register('/subsite/sw.js')會給你一個範圍/subsite,這是你想要的註冊。
  • navigator.serviceWorker.register('/subsite/sw.js', {scope: '/subsite'})會工作,但它再次,不會給你任何好處超過默認行爲。

我只建議明確設置options.scope的值的唯一時間是當您需要顯式限制服務工作者的範圍比默認範圍更窄時。

請注意,如果你決定爲options.scope提供一個值,該值是像'./'相對URL,URL被解釋爲相對於腳本/頁面調用register()的位置。 {scope: './'}而不是被解釋爲相對於服務工作者腳本URL的位置。我很困惑這一點,所以花一些時間來充分理解那裏的含義。這就解釋了爲什麼你在最初的問題中結束了多次註冊。

+2

我修復了MDN頁面。 – StormyKnight

相關問題