说明
使用 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 之前的 Chrome 版本中,声明 "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、embed、object)。默认值为清单条目的
can_embed值。当enabled为 false 时,此属性没有任何影响。 -
已启用
布尔值 (可选)
此处理程序是否已启用。默认值为清单条目的
enabled值。
StreamInfo
属性
-
嵌入式播放器
布尔值
如果是在嵌入式上下文(iframe/embed/object)中加载,则为 true。
-
mimeType
字符串
被拦截内容的 MIME 类型。
-
originalUrl
字符串
用户访问的原始网址。
-
responseHeaders
对象
HTTP 响应标头(键值对)。
-
streamUrl
字符串
用于提取直播数据的网址。
-
tabId
数值
包含文档的标签页 ID。
方法
abortAndFallbackToNativeHandler()
chrome.mimeHandler.abortAndFallbackToNativeHandler(): Promise<void>
中止当前流处理,并将内容移交给用户代理的原生处理程序。此调用之后,扩展程序框架将被销毁;调用方不应期望进一步执行。
返回
-
承诺<void>
getMimeHandlerOptions()
chrome.mimeHandler.getMimeHandlerOptions(
mimeType: string,
): Promise<MimeHandlerOptions>
读取 MIME 类型的选项。每个成员都是扩展程序设置的值,如果扩展程序未设置,则为清单条目的值。
参数
-
mimeType
字符串
要读取其选项的 MIME 类型。它必须是扩展程序通过 mime_types_handler 处理的 MIME 类型。
返回
-
Promise<MimeHandlerOptions>
Promise 已通过 MIME 类型的选项进行解析。
getStreamInfo()
chrome.mimeHandler.getStreamInfo(): Promise<StreamInfo>
检索当前 MIME 处理程序上下文的流信息。必须从 MIME 处理程序扩展程序页面中调用。
返回
-
Promise<StreamInfo>
setMimeHandlerOptions()
chrome.mimeHandler.setMimeHandlerOptions(
mimeType: string,
options: MimeHandlerOptions,
): Promise<void>
为指定的 MIME 类型设置配置选项。如果扩展程序在拆分无痕模式下运行,则在无痕模式下设置的选项仅适用于无痕模式,并会持续到无痕式会话结束。未在无痕模式下设置的选项会沿用在无痕模式之外设置的值。
参数
-
mimeType
字符串
要配置的 MIME 类型。它必须是扩展程序通过 mime_types_handler 处理的 MIME 类型。
-
要更改的选项。
返回
-
承诺<void>
设置配置后,Promise 会解析。