在我的应用程序中,用户可以加载自定义内容,例如第三方托管图像。我有具体的目标(为了安全):
image-src
的 CSP。它还允许浏览器处理诸如图像源的 CSP 验证之类的事情,然后主机可以信任图像的数据 URL。img-src
仅允许来自该图像主机源的图像。为了将图像“传输”到主机,我需要一个 blob/数据 URL/对象 URL。我尝试过以下解决方案:
fetch()
对图像 URL 发出 HTTP 请求并获取 Blob。这被视为 connect-src
而不是 img-src
并且“引发”安全问题。<img>
,动态创建<canvas>
,使用canvas.getContext('2d').drawImage(img, 0, 0)
(和/或相关API),最后使用canvas.toBlob()
。这对于 JPEG 和 PNG 非常有用,但只抓取 GIF 的第一帧,不包括 SVG 的原始源。理想情况下,我正在寻找面向图像的API(以便尊重
img-src
)。例如:
fetch()
期待图像?createImageBitmap()
中的 <img>
等 API,但在加载的图像中使用 所有数据。<img>
上使用API将其“转移”到不同的上下文(例如“沙盒”iframe到“主机”)。这可能吗?
我认为您正在寻找帖子消息。
https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage
这是在 iframe 和主机之间发送数据的方式。 向 iframe 发送“检索图像”消息。拥有 iframe
fetch()
图像 blob,然后将 response.blob()
发送回主机
// send a message to the iframe to request the image
function sendMessage() {
const message = 'retrieve image'
const iframe = document.querySelector("iframe");
iframe.contentWindow.postMessage(message, "*");
}
// in the iframe receive the message
window.addEventListener('message', receiveMessage, false);
// in the iframe handle featching the image and sending a message back
function receiveMessage(event) {
if (event.origin === 'https://allowedoroigin.com') {
const imageBlob = '[imageData]' // fetch the image and get the blob
window.parent.postMessage(message, imageBlob);
}
}
// back in the parent frame recieve and handle the message
window.addEventListener('message', receiveMessage, false);
免责声明:这是一个要点而不是完整的代码,您需要将各个部分放在正确的位置并处理获取图像,使用标准获取并对结果运行 blob() 方法。