new Worker(new URL("./worker.js", import.meta.url))。這個呼叫會在 dist/<browser>/ 根目錄產出一個獨立的 worker chunk,編譯後的呼叫透過 chrome.runtime.getURL() 指向該 chunk。這一段是正常的。
拒絕發生在瀏覽器這一側。worker 指令碼必須與建立它的文件同源。內容指令碼背後的文件是宿主頁面,所以下面兩種寫法都會失敗。
內容指令碼實際得到的結果
下面這段內容指令碼可以順利編譯,執行期失敗:https://example.com 上,Chromium 回報:
web_accessible_resources 也解除不了這項限制。它控制的是頁面能不能載入該檔案,而不是該檔案能不能成為外部來源的 worker。
以上是在 Chromium
上、以執行於公開頁面的內容指令碼實測的結果。Firefox 與 Safari
並未實測,因此請把上面的錯誤視為 Chromium 的行為。
在擴充功能自己的頁面執行 worker
popup、選項頁、側邊欄與 offscreen 文件都從chrome-extension:// 來源載入。在那裡建立的 worker 是同源的,兩種寫法都不需要額外設定:
blob 變通做法與它的兩個前提
當這項工作必須留在頁面內時,請取回 worker 原始碼,並以 blob URL 建構 worker。blob 會繼承頁面的來源,因此瀏覽器會接受:extension build 不會把 worker chunk 加入 web_accessible_resources,所以請自己在 manifest.json 宣告該檔案:
fetch 會以 TypeError: Failed to fetch 失敗,請求顯示為 chrome-extension://invalid/。
宿主頁面的 CSP 必須允許 blob worker。 送出 worker-src 'self' 的頁面會擋下該 blob,而且失敗是安靜的。建構函式正常返回,接著 worker 透過 onerror 失敗,訊息是空的:
new Worker 外面的 try/catch 完全攔不到它。請掛上 onerror 處理器,並把它當成真正的失敗訊號。
三種做法的取捨
- 擴充功能頁面不需要任何設定,兩種寫法都可用。
- 內容指令碼加 blob 需要一條資訊清單條目,以及寬鬆的頁面 CSP。
- 內容指令碼直接用擴充功能 URL 會被拒絕,沒有辦法改變。
後續步驟
- 閱讀 Offscreen 文件,了解沒有可見頁面的背景工作。
- 閱讀可供網頁存取的資源,了解資訊清單條目。
- 閱讀內容指令碼,了解頁面來源還限制了什麼。

