fetch 呼叫,在 content script 裡和在 background 裡表現並不相同。
Extension.js 不會改動這些規則中的任何一條。它確實會為自己的開發伺服器設定標頭,也確實會在開發期修補 CSP。這兩件事都在下面說明。
請求在哪裡執行,就由哪一套規則決定
就網路而言,content script 與頁面共用同一個 origin。host 權限在那裡並不能解除 CORS。這是最常見的一個意外。
把請求移到 background
可靠的做法是讓 background 去 fetch,再把結果送回來:src/content/scripts.js
src/background.js
宣告 host 權限
background 只有對 manifest 點名的 origin 才豁免 CORS:manifest.json
<all_urls> 能用,但商店審核者會追問它。
Preflight 請求依然會發生
host 權限拿掉的是對回應的 origin 檢查,它拿不掉 preflight。 帶自訂標頭的請求,或是用了GET、HEAD、POST 以外方法的請求,仍然會先送出一個 OPTIONS 請求。伺服器必須回應它。伺服器在你手上時,就放行你送出的方法與標頭。不在你手上時,就把請求保持簡單。
Extension.js 開發伺服器
在extension dev 期間,Extension.js 會執行一個本機伺服器,用來提供重新載入的用戶端與熱更新。任何頁面上的 content script 都會撥向它,這本身就是一次跨來源請求,所以伺服器回以:
Host 標頭。這是一個跑在你自己機器上的開發伺服器。它永遠不會出現在打包後的擴充功能裡,它提供的任何東西也不會進入正式環境。
只在開發期生效的 CSP 修補
除非你自己設定,否則 Manifest v3 不會限制connect-src。因此一個沒有宣告 content_security_policy 的專案不需要任何修補,開發用的 manifest 帶的就是一般政策:
dist/chromium/manifest.json
connect-src,開發建置就會把本機 origin 附加進去,這樣你的頁面仍然連得上那個 socket:
dist/chromium/manifest.json
extension build 時移除,你自己的 connect-src 則會保留。所以一份漏掉你 API origin 的嚴格政策,會在開發期通過、在正式環境失敗。當一個 CSP 錯誤一路活到正式環境時,請閱讀 Manifest 拒絕。
綁定到另一個主機
在容器裡開發時,把伺服器綁到別處:0.0.0.0,所以 Extension.js 會為用戶端解析出一個連得上的位址,退回值是 127.0.0.1。當瀏覽器在另一台機器上時,請覆寫它:
遠端腳本與樣式表
擴充功能的 CSP 禁止把遠端 origin 上的腳本載入擴充功能頁面。那不是 CORS,任何標頭都修不好它。請改為把程式碼打包進來。 Extension.js 會在建置期回報這種情況:症狀與修正
最佳實務
- 把每一個第三方請求都放進 background,包括今天還能正常運作的那些。
- 在
host_permissions裡逐一點名 origin,而不是伸手去拿<all_urls>。 - 發佈之前先用正式建置測一遍。開發期比較寬鬆是刻意的。
下一步
- 在 Messaging 中了解如何在情境之間傳遞資料。
- 檢視 權限與 host 權限。
- 用 攔截網路請求 觀察流量。

