Chrome 内容和后台脚本可以共享对 blob: URL 的访问吗?

Can Chrome content and background scripts share access to blob: URLs?

我正在 Chrome 扩展内容脚本中创建一个 getUserMedia 流,我想将其传递给后台脚本。

你不能在它们之间传递非 JSON 的数据,所以我的策略是将生成的 blob URL 传递给流。

内容脚本:

function get_stream() {
    navigator.mediaDevices.getUserMedia({video: 1}).then(stream => {
        chrome.runtime.sendMessage({action: 'got_stream', params: {stream_url: URL.createObjectURL(stream)}});
    });

后台脚本:

chrome.runtime.onMessage.addListener(function(data) {
    switch (data.action) {
        case 'got_stream': got_stream(data.params); break;
    }
});

function got_stream(params) {
    let vid = document.createElement('video');
    alert(params.stream_url); //blob:http://...
    vid.src = params.stream_url; //error - file not found
}

这很好...直到我尝试将它应用于生成的 <video /> 元素,此时控制台显示找不到文件。

我认为这是因为后台和内容脚本处于沙盒环境中。

有没有什么办法可以解决这个问题,而不必像通过 WebRTC 或其他方式逐字传输流那样做一些核心的事情?

blob url 可能绑定到来源,所以我认为这行不通。请参阅适配器存储库中的一些讨论 here

您是否尝试过在内容和后台脚本之间创建 RTCPeerConnection 并以此方式发送流?由于多种原因并不理想,但总比没有好。

我发现这是一个起源问题。

内容脚本 运行 在当前网页的上下文中,而背景脚本 运行 在扩展的上下文中。

Blob URLs 按来源分组,因此,以同样的方式,您通常不能 AJAX 从一个域到另一个域,两个域也不能共享 blob URLs.

这通过 运行 解决当前网页中的内容脚本(因此未在 content_scripts 下的清单中指定)但在新选项卡或弹出窗口中。

背景:

window.open('content-page.html');

内容页:

<script src='content-script.js'></script>

然后,由 content-script.js 生成的任何 blob URL 都将在后台可读,因为它们现在都 运行ning 在扩展的上下文中,即共享来源。

[编辑]

如果您不喜欢弹出窗口 window 的想法(毕竟,在 Mac 上,它们呈现为完整的选项卡),您可以注入一个 iframe 进入当前选项卡并从那里 运行 您的内容脚本。

为此,请从您的清单中调用内容脚本:

{
    "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["content-script-curr-tab.js"]
    }]
}

然后在那:

let ifr = document.createElement('iframe');
ifr.setAttribute('allow', 'microphone; camera'); //necessary for cross-origin frames that request permissions
ifr.style.display = 'none';
ifr.src = chrome.runtime.getURL('page-to-inject-into-iframe.html');
document.body.appendChild(ifr);

注意 chrome.runtime.getURL() - 这是在扩展而非网页的上下文中托管和 运行 页面的关键。

然后,最后,在page-to-inject-into-iframe.html

<script src='script-to-inject-into-iframe.js'></script>

那就在那里做你的事吧!