如何在清单 v3 扩展 ServiceWorker 中使用 URL.createObjectURL

问题描述 投票:0回答:2

我的扩展创建 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 中执行此操作?

javascript service-worker chrome-extension-manifest-v3
2个回答
0
投票

您可以将 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",
    });
  });
});

0
投票

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);
});
© www.soinside.com 2019 - 2024. All rights reserved.