說明
使用 chrome.mimeHandler API 處理第三方擴充功能中的 MIME 類型串流。
可用性
資訊清單
概念和用途
過去,處理特定文件類型的第三方擴充功能 (例如 PDF 檢視器) 仰賴網路要求攔截功能,來擷取導覽並將使用者重新導向至擴充功能頁面。註冊為 MIME 處理常式可避免該方法的幾項限制:
- 網址列會保留來源網址,不會替換成
chrome-extension://網址。 - 擴充功能會擷取 Chrome 已收到的回應,而不是提出第二個網路要求。透過 POST 要求或單次使用網址傳送的文件可正常運作。
- 擴充功能可以轉譯在
<embed>、<object>或<iframe>元素中載入的文件。 - 使用者不必在擴充功能設定中手動啟用「允許存取檔案網址」,即可使用本機檔案 (
file://網址)。
MIME 處理常式僅適用於佔據整個框架的文件:頂層導覽和內嵌文件。不適用於內嵌子資源 (例如 <audio>、<img> 或 <video> 元素)。
註冊處理常式
如要將擴充功能註冊為 MIME 處理常式,請在資訊清單中宣告 "mime_types_handler" 鍵。每個項目都會將 MIME 類型對應至轉譯該類型的擴充功能頁面:
manifest.json:
{
"name": "My PDF Viewer",
...
"mime_types_handler": {
"application/pdf": {
"handler_url": "viewer.html",
"can_embed": true
}
},
...
}
將 "can_embed" 設為 true,即可一併處理嵌入 <embed>、<object> 或 <iframe> 元素的文件。如果省略,處理常式只會接收頂層導覽。自 Chrome 151 起,application/pdf 是公開處理常式唯一可用的 MIME 類型;宣告不支援的 MIME 類型會導致安裝警告。
如果有多個已安裝的擴充功能註冊相同的 MIME 類型,則由最近安裝的擴充功能處理。如果解除安裝該擴充功能,先前安裝的處理常式會再次生效。
擷取串流資訊
使用者開啟已註冊 MIME 類型的文件時,Chrome 會載入處理常式頁面,而非內建檢視器。在處理常式頁面中,呼叫 getStreamInfo() 擷取 StreamInfo 物件。包括使用者前往的 originalUrl、HTTP responseHeaders、文件是否在 embedded 情境中載入,以及可用於擷取文件內容的 streamUrl。
streamUrl 只能擷取一次,且只能從擴充功能的來源擷取。請先完整讀取回應,再進行處理;第二次擷取相同的 streamUrl 會失敗。顯示文件的位置或標題時,請使用 originalUrl,不要擷取內容,因為原始要求可能無法重複。
改用原生處理常式
處理常式可能會遇到無法轉譯的文件,例如損毀或受密碼保護的檔案。呼叫 abortAndFallbackToNativeHandler() 停止處理文件,並將文件交回 Chrome 的內建檢視器,而不是讓使用者停留在損壞的頁面。Chrome 會卸載處理常式頁面,做為備用方案的一部分;這項呼叫後不會執行任何程式碼。
Chrome 會在處理常式執行時緩衝處理回應。如果呼叫這個方法時已完整收到回應,Chrome 會從緩衝副本提供內建檢視器,不會發出新的網路要求。否則,Chrome 會從網路重新載入文件,這可能會導致透過 POST 或單次使用網址傳送的文件失敗。請先完整擷取串流,再決定是否可以轉譯;streamUrl 擷取完成後,Chrome 就會取得完整回應。
處理 API 可用性
在 Chrome 151 之前的版本中,宣告 "mime_types_handler" 的擴充功能仍會安裝並執行,但不會註冊為處理常式,且 browser.mimeHandler 未定義。從網路要求攔截功能遷移的擴充功能,可以在啟動時檢查 API,並保留現有方法做為備用方案:
service-worker.js:
if (browser.mimeHandler) {
// Chrome routes registered MIME types to the handler page
// declared in the manifest.
} else {
// Fall back to network request interception.
}
範例
處理串流
以下範例會在資訊清單中宣告的處理常式頁面中執行。它會擷取文件內容,如果轉譯失敗,則會改用 Chrome 內建的檢視器:
viewer.js:
async function loadDocument() {
const streamInfo = await browser.mimeHandler.getStreamInfo();
// The `embedded` property is true if the document is loaded
// within an <embed>, <object>, or <iframe> element.
if (streamInfo.embedded) {
// Adjust the UI (e.g., hide the top navigation bar).
document.body.classList.add('embedded-view');
}
// Fetch the content using the provided streamUrl. The stream can
// only be consumed once, so read it fully before continuing.
const response = await fetch(streamInfo.streamUrl);
const data = await response.arrayBuffer();
try {
// Render the document (e.g., using PDF.js).
await renderDocument(data);
} catch (e) {
// Can't render this document. Fall back to Chrome's built-in
// viewer; the page unloads and no code runs after this call.
browser.mimeHandler.abortAndFallbackToNativeHandler();
}
}
loadDocument();
允許使用者切換處理方式
系統會依 MIME 類型儲存處理常式選項。以下範例使用 getMimeHandlerOptions() 和 setMimeHandlerOptions(),讓使用者在選項頁面關閉處理功能,而不必解除安裝擴充功能。停用處理功能後,該類型的文件就不會再轉送至擴充功能。
options.js:
const checkbox = document.querySelector('#handle-pdfs');
async function initOptions() {
const options =
await browser.mimeHandler.getMimeHandlerOptions('application/pdf');
// Handling is enabled unless it has been explicitly disabled.
checkbox.checked = options.enabled !== false;
}
checkbox.addEventListener('change', async () => {
await browser.mimeHandler.setMimeHandlerOptions('application/pdf', {
enabled: checkbox.checked
});
});
initOptions();
類型
MimeHandlerOptions
屬性
-
canEmbed
布林值 選填
Chrome 157 以上版本這個處理常式是否可用於嵌入式載入 (iframe、嵌入、物件)。預設為資訊清單項目的
can_embed值。如果enabled為 false,則不會生效。 -
已啟用
布林值 選填
這個處理常式是否已啟用。預設為資訊清單項目的
enabled值。
StreamInfo
屬性
-
embedded
布林值
如果是在嵌入式情境 (iframe/embed/object) 中載入,則為 True。
-
mimeType
字串
攔截內容的 MIME 類型。
-
originalUrl
字串
使用者前往的來源網址。
-
responseHeaders
物件
HTTP 回應標頭 (鍵/值組合)。
-
streamUrl
字串
要擷取串流資料的網址。
-
tabId
數字
含有文件的分頁 ID。
方法
abortAndFallbackToNativeHandler()
browser.mimeHandler.abortAndFallbackToNativeHandler(): Promise<void>
中止目前的串流處理,並將內容交給使用者代理程式的原生處理常式。呼叫後,擴充功能框架會遭到拆除,呼叫端不應預期進一步執行。
傳回
-
承諾<void>
getMimeHandlerOptions()
browser.mimeHandler.getMimeHandlerOptions(
mimeType: string,
): Promise<MimeHandlerOptions>
讀取 MIME 類型的選項。每個成員都是擴充功能設定的值,如果擴充功能未設定,則為資訊清單項目的值。
參數
-
mimeType
字串
要讀取選項的 MIME 類型。必須是擴充功能透過 mime_types_handler 處理的 MIME 類型。
傳回
-
Promise<MimeHandlerOptions>
Promise 已解析,並提供 MIME 類型的選項。
getStreamInfo()
browser.mimeHandler.getStreamInfo(): Promise<StreamInfo>
擷取目前 MIME 處理常式內容的串流資訊。必須從 MIME 處理常式擴充功能頁面內呼叫。
傳回
-
Promise<StreamInfo>
setMimeHandlerOptions()
browser.mimeHandler.setMimeHandlerOptions(
mimeType: string,
options: MimeHandlerOptions,
): Promise<void>
設定指定 MIME 類型的設定選項。如果擴充功能在分割無痕模式下執行,從無痕模式設定的選項只會套用至無痕模式,並在無痕模式工作階段結束後失效。未在無痕模式中設定的選項,會沿用無痕模式外的設定值。
參數
-
mimeType
字串
要設定的 MIME 類型。必須是擴充功能透過 mime_types_handler 處理的 MIME 類型。
-
要變更的選項。
傳回
-
承諾<void>
設定完成後,Promise 就會解析。