chrome.offscreen 按需建立。
設定
在manifest.json 中請求權限:
manifest.json
pages/ 特殊資料夾宣告,Extension.js 會像處理其他 HTML 進入點一樣編譯它:
pages/offscreen.html
建立、重複使用、關閉
Chrome 每個擴充功能只允許存在一個 offscreen document,當已經有一個時再呼叫createDocument 會丟出例外。可靠的做法是先用一個 ensure 函式檢查是否已有現存的文件:
background.ts
creating 這把鎖很重要:兩個事件可能會在文件尚未存在前競相進入 ensureOffscreen,而第二次的 createDocument 呼叫就會丟出例外。
工作完成後關閉它以釋放記憶體:
選擇 reason
reasons 陣列會告訴 Chrome 這份文件為何存在。常見的值有:
有一個行為值得留意:使用
AUDIO_PLAYBACK 時,Chrome 會在音訊停止播放後約 30 秒自動關閉該文件。其他 reason 下,文件會一直存在,直到你關閉它或擴充功能卸載為止。
從背景存取剪貼簿
寫入剪貼簿是需要 offscreen document 最常見的理由。navigator.clipboard 位於 window 上,
而 Manifest V3 的 service worker 沒有 window,因此寫入必須發生在一個真正的頁面上。
請求權限並給出對應的 reason:
manifest.json
pages/offscreen.html
pages/offscreen.ts
background.ts
chrome.offscreen.Reason.CLIPBOARD 傳給 createDocument。
document.execCommand("copy") 才是這裡可行的呼叫。較新的
navigator.clipboard.writeText 需要一個取得焦點的文件,而 offscreen document 永遠不會取得焦點。
讀取剪貼簿需要 clipboardRead 權限,以及同一份文件。
內容腳本,或使用者自己開啟的擴充功能頁面,都不需要這一套。兩者都有真正的 window,因此在一次使用者手勢之後,navigator.clipboard.writeText 就能運作。
Extension.js 會幫你打包這個頁面
chrome.offscreen.createDocument 接收的是一個 URL 字串,而不是 import。Extension.js
會在建置期間讀取這個字串,並把該 HTML 頁面以及頁面載入的一切都加進輸出。就算只有 service worker
提到過這個頁面,它一樣會進到 dist/。
這個字串必須是純字面值才行。在執行階段組出來的 URL 對建置是不可見的,頁面就會被漏掉。
與文件通訊
Offscreen documents 使用標準的 runtime messaging。請為你的訊息加上範圍標記,讓其他介面可以忽略它們:pages/offscreen.ts
Firefox
Firefox 並未實作chrome.offscreen。它的 Manifest V3 背景以 event page 的形式執行,原本就具備 DOM 存取能力,因此同樣的 DOM 工作可以直接在背景腳本中執行。請使用瀏覽器專屬的 manifest 欄位搭配能力檢查(typeof chrome.offscreen !== "undefined")來進行分支處理。

