You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Firefox扩展截图下载功能报错求助:downloads.download访问被拒

解决Firefox中browser.downloads.download无法处理截图data URI的问题

错误原因

Firefox的downloads.download API不支持直接传入data URI作为url参数,即使配置了<all_urls>权限也无效——因为data URI不属于标准HTTP/HTTPS等协议范畴,权限规则不覆盖这类URI。

正确实现方案

需要将captureVisibleTab返回的data URI解码为二进制Blob,再通过URL.createObjectURL生成可被下载API识别的Blob URL,最后完成下载操作。同时要注意在下载完成后释放Blob URL,避免内存泄漏。

修正后的完整代码:

function takeScreenshotAndSave() {
  browser.tabs.captureVisibleTab({ format: "png" })
    .then(screenshotUrl => {
      console.log("Screenshot URL:", screenshotUrl);
      const filename = `Capture-snapshot${Date.now()}-visible-1.png`;

      // 将data URI转换为Blob对象
      const byteString = atob(screenshotUrl.split(',')[1]);
      const mimeString = screenshotUrl.split(',')[0].split(':')[1].split(';')[0];
      const ab = new ArrayBuffer(byteString.length);
      const ia = new Uint8Array(ab);
      for (let i = 0; i < byteString.length; i++) {
        ia[i] = byteString.charCodeAt(i);
      }
      const blob = new Blob([ab], { type: mimeString });
      const blobUrl = URL.createObjectURL(blob);

      // 执行下载
      browser.downloads.download({
        url: blobUrl,
        filename: filename,
        conflictAction: "uniquify",
      })
      .then(downloadId => {
        // 下载完成后释放Blob URL
        browser.downloads.onChanged.addListener(function listener(delta) {
          if (delta.id === downloadId && delta.state && delta.state.current === "complete") {
            URL.revokeObjectURL(blobUrl);
            browser.downloads.onChanged.removeListener(listener);
          }
        });
      })
      .catch(error => {
        console.error("Error downloading screenshot:", error);
        URL.revokeObjectURL(blobUrl); // 下载失败也释放URL
      });
    })
    .catch(error => {
      console.error("Error taking screenshot:", error);
    });
}

关于之前Blob方案的问题说明

你之前尝试的Blob方案生成的是data URI字符串文件,大概率是因为没有正确解码data URI的二进制部分——直接将完整的data URI字符串存入Blob,而非解码后的二进制数据,导致文件内容是文本格式的URI而非PNG二进制流。

权限确认

你的manifest.json权限配置已经足够:

"permissions": [
  "notifications",
  "activeTab",
  "downloads",
  "<all_urls>"
],

注意:activeTab权限需要通过用户手势触发(比如按钮点击),确保你的函数是在用户交互时调用的,否则可能无法获取标签页权限。

内容的提问来源于stack exchange,提问作者user173026

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 04:43:11