說明
使用 offscreen API 建立及管理螢幕外文件。
權限
offscreen如要使用 Offscreen API,請在擴充功能資訊清單中宣告 "offscreen" 權限。例如:
{
"name": "My extension",
...
"permissions": [
"offscreen"
],
...
}
可用性
概念和用途
Service Worker 無法存取 DOM,且許多網站的內容安全政策會限制內容指令碼的功能。Offscreen API 可讓擴充功能在隱藏文件中使用 DOM API,不必開啟新視窗或分頁,因此不會干擾使用者體驗。runtime API 是唯一支援離螢幕文件的擴充功能 API。
載入為螢幕外文件的頁面,處理方式與其他類型的擴充功能頁面不同。
擴充功能的權限會沿用至螢幕外文件,但擴充功能 API 存取權會受到限制。舉例來說,由於 browser.runtime API 是螢幕外文件唯一支援的擴充功能 API,因此必須使用該 API 的成員處理訊息。
以下是螢幕外文件與一般網頁的其他行為差異:
- 螢幕外文件的網址必須是與擴充功能綁定的靜態 HTML 檔案。
- 無法聚焦於螢幕外文件。
- 螢幕外文件是
window的例項,但其opener屬性的值一律為null。 - 雖然擴充功能套件可以包含多個螢幕外文件,但已安裝的擴充功能一次只能開啟一個。如果擴充功能在分割模式下執行,且有無痕模式設定檔,則一般和無痕模式設定檔各可有一個螢幕外文件。
使用 browser.offscreen.createDocument() 和 browser.offscreen.closeDocument() 建立及關閉畫面外文件。createDocument() 需要文件的 url、原因和理由:
browser.offscreen.createDocument({
url: 'off_screen.html',
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
原因
如需有效原因清單,請參閱「原因」一節。建立文件時會設定原因,以決定文件的生命週期。AUDIO_PLAYBACK 原因會將文件設為在 30 秒內未播放音訊時關閉。其他原因則不會設定生命週期限制。
範例
維護螢幕外文件的生命週期
以下範例說明如何確保螢幕外文件存在。setupOffscreenDocument() 函式會呼叫 runtime.getContexts() 尋找現有的螢幕外文件,如果文件不存在,則會建立文件。
let creating; // A global promise to avoid concurrency issues
async function setupOffscreenDocument(path) {
// Check all windows controlled by the service worker to see if one
// of them is the offscreen document with the given path
const offscreenUrl = browser.runtime.getURL(path);
const existingContexts = await browser.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [offscreenUrl]
});
if (existingContexts.length > 0) {
return;
}
// create offscreen document
if (creating) {
await creating;
} else {
creating = browser.offscreen.createDocument({
url: path,
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
await creating;
creating = null;
}
}
將訊息傳送至螢幕外文件前,請呼叫 setupOffscreenDocument(),確認文件是否存在,如以下範例所示。
browser.action.onClicked.addListener(async () => {
await setupOffscreenDocument('off_screen.html');
// Send message to offscreen document
browser.runtime.sendMessage({
type: '...',
target: 'offscreen',
data: '...'
});
});
如需完整範例,請參閱 GitHub 上的 offscreen-clipboard 和 offscreen-dom 示範。
Chrome 116 之前:檢查螢幕外文件是否開啟
runtime.getContexts() 是在 Chrome 116 中新增。在舊版 Chrome 中,請使用 clients.matchAll() 檢查現有的螢幕外文件:
async function hasOffscreenDocument() {
if ('getContexts' in browser.runtime) {
const contexts = await browser.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [OFFSCREEN_DOCUMENT_PATH]
});
return Boolean(contexts.length);
} else {
const matchedClients = await clients.matchAll();
return matchedClients.some(client => {
return client.url.includes(browser.runtime.id);
});
}
}
類型
CreateParameters
屬性
-
理由
字串
開發人員提供的字串,詳細說明需要背景資訊的原因。使用者代理程式「可能」會使用這個值向使用者顯示。
-
原因
原因[]
擴充功能建立螢幕外文件的原因。
-
網址
字串
要在文件中載入的 (相對) 網址。
Reason
列舉
「TESTING」
僅供測試使用的原因。
"AUDIO_PLAYBACK"
指定由螢幕外文件負責播放音訊。
"IFRAME_SCRIPTING"
指定螢幕外文件需要嵌入 iframe 並編寫指令碼,才能修改 iframe 的內容。
"DOM_SCRAPING"
指定螢幕外文件需要嵌入 iframe 並擷取其 DOM 以擷取資訊。
"BLOBS"
指定螢幕外文件需要與 Blob 物件互動 (包括 URL.createObjectURL())。
"DOM_PARSER"
指定螢幕外文件必須使用 DOMParser API。
"USER_MEDIA"
指定螢幕外文件需要與使用者媒體的媒體串流互動 (例如 getUserMedia())。
"DISPLAY_MEDIA"
指定螢幕外文件需要與螢幕媒體 (例如 getDisplayMedia()) 的媒體串流互動。
"WEB_RTC"
指定螢幕外文件需要使用 WebRTC API。
"CLIPBOARD"
指定螢幕外文件需要與 Clipboard API 互動。
"LOCAL_STORAGE"
指定螢幕外文件需要存取 localStorage。
"WORKERS"
指定螢幕外文件需要產生 worker。
"BATTERY_STATUS"
指定螢幕外文件需要使用 navigator.getBattery。
"MATCH_MEDIA"
指定螢幕外文件必須使用 window.matchMedia。
"GEOLOCATION"
指定螢幕外文件需要使用 navigator.geolocation。
方法
closeDocument()
browser.offscreen.closeDocument(): Promise<void>
關閉目前開啟的擴充功能螢幕外文件。
傳回
-
承諾<void>
在關閉螢幕外文件時解析的 Promise。
createDocument()
browser.offscreen.createDocument(
parameters: CreateParameters,
): Promise<void>
為擴充功能建立新的螢幕外文件。
參數
-
parameters
描述要建立的螢幕外文件的參數。
傳回
-
承諾<void>
在螢幕外文件建立並完成初始載入網頁時,解析的 Promise。
hasDocument()
browser.offscreen.hasDocument(): Promise<boolean>
判斷擴充功能是否有使用中的文件。
傳回
-
Promise<boolean>
Promise,會根據擴充功能是否有有效的螢幕外文件,解析出結果。