我的扩展创建 zip 存档,其中包含图像。我使用 chrome.downloads.download 将我的存档下载到设备。
const url = URL.createObjectURL(archiveBlob);
chrome.downloads.download({
url,
filename: `${archiveData.fileName}.zip`,
saveAs: false
});
当我将 ArrayBuffer 转换为 Image 时,我的扩展中还需要 URL.createObjectURL
async bufferToImage(buffer: ArrayBuffer): Promise<InstanceType<typeof Image>> {
return new Promise((res, rej) => {
const blob = new Blob([buffer]);
const objectURL = URL.createObjectURL(blob);
const img = new Image();
img.src = objectURL;
img.onload = () => res(img);
});
}
我现在如何在 Manifest v3 ServiceWorker 中执行此操作?
您可以将 Blob 转换为 base64。
如果您想导出图像:
/**
* capture and download
* 截图并下载
*/
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
chrome.tabs.query({ active: true }, async (tabs) => {
const tab = tabs[0];
const image = await chrome.tabs.captureVisibleTab(tab.windowId, {
format: "png",
});
chrome.downloads.download({
url: image,
filename: "1.png",
})
});
});
如果您想导出 zip:
import JSZip from "jszip";
/**
* example: captureVisibleTab and export zip
* 案例:截图并导出zip
*/
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
chrome.tabs.query({ active: true }, async (tabs) => {
const tab = tabs[0];
// capture
const image = await chrome.tabs.captureVisibleTab(tab.windowId, {
format: "png",
});
// image base64 => blob
const blob = await fetch(image).then((response) => response.blob());
// zip image
const zip = new JSZip();
zip.file("insta-snap1.png", blob, { binary: true });
const zipData = await zip.generateAsync({
type: "base64",
});
// download zip with base64
chrome.downloads.download({
url: `data:application/octet-stream;base64,${zipData}`,
filename: "test.zip",
});
});
});
TL;DR:使用数据 URL。由于潜在的
内存泄漏,Service Workers 没有
URL.createObjectURL
。
URL.createObjectURL
在做什么以及我们为什么使用它?这个小函数做了一些我们认为理所当然的事情,当我们将它与像
chrome.download
这样的函数一起使用时。
因为它需要 Blob 对象,所以我们已经提供了内容(参数 1)和
type
(参数 2;选项)。
URL.createObjectURL
的返回值不仅仅是任何URL。此 URL 是存储您提供的内容的结果。尝试访问这些 URL,这是您的内容正在托管。
例如“你好世界” =>
URL.createObjectURL
=> blob:chrome-extension://.../<uuid>
=> “你好世界”
现在,对于我们使用
chrome.downloads
时的示例,通过提供返回的 URL 值作为 url
参数,当您的内容被重试下载时,会自动分配文件类型和文件名。
因此,如果您想复制此功能:
// creating a Zip file download prompt
// external variables: archiveData, archiveBlob
const data = btoa(archiveBlob);
const filename = `${archiveData.fileName}.zip`;
const mediatype = "application/octet-stream";
const url = `data:${mediatype};base64,${data}`;
chrome.downloads.download({
filename,
url,
});
// base64 binary image data and provide URL to load it
return new Promise((res, rej) => {
const blob = btoa(buffer);
const objectURL = `data:;base64,${blob}`;
const img = new Image();
img.src = objectURL;
img.onload = () => res(img);
});