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

如何用JavaScript调用下载页面并通过XPCOM保存(Firefox45扩展)

嘿,刚好熟悉Firefox旧版扩展的这套操作,给你整一个适配Firefox 45的完整实现,完全符合你的要求——不用Ajax/jQuery,纯原生JS+XPCOM搞定:

完整实现代码
function downloadAndSaveFile(url, defaultFileName) {
  // 1. 创建XHR请求获取Blob数据
  const xhr = new XMLHttpRequest();
  xhr.open('GET', url, true);
  xhr.responseType = 'blob'; // 指定返回类型为Blob,直接拿到二进制数据

  xhr.onload = function() {
    if (xhr.status === 200) {
      const blob = xhr.response;
      // 2. 调用XPCOM组件将Blob保存到本地
      saveBlobToLocal(blob, defaultFileName);
    } else {
      console.error('文件下载失败,状态码:', xhr.status);
    }
  };

  xhr.onerror = function() {
    console.error('请求过程中发生错误,请检查链接或网络');
  };

  xhr.send();
}

function saveBlobToLocal(blob, defaultFileName) {
  // 初始化XPCOM文件选择器组件
  const filePicker = Components.classes["@mozilla.org/filepicker;1"]
                               .createInstance(Components.interfaces.nsIFilePicker);
  
  // 设置选择器模式为“保存文件”,绑定当前窗口
  filePicker.init(window, '选择保存位置', Components.interfaces.nsIFilePicker.modeSave);
  filePicker.defaultString = defaultFileName;
  // 添加文件类型过滤器,这里以PDF为例
  filePicker.appendFilter('PDF文档', '*.pdf');
  filePicker.appendFilter('所有文件', '*.*');

  // 弹出选择对话框,获取用户操作结果
  const pickerResult = filePicker.show();
  if (pickerResult === Components.interfaces.nsIFilePicker.returnOK || 
      pickerResult === Components.interfaces.nsIFilePicker.returnReplace) {
    
    // 获取用户选中的文件对象
    const targetFile = filePicker.file;
    // 初始化文件输出流组件
    const outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
                                   .createInstance(Components.interfaces.nsIFileOutputStream);
    
    // 打开文件:写模式+创建文件(不存在时)+截断原有内容,权限设为0666
    outputStream.init(targetFile, 0x02 | 0x08 | 0x20, 0o666, 0);
    
    // 将Blob转换为字节数组写入流
    const reader = new FileReader();
    reader.onload = function() {
      const arrayBuffer = reader.result;
      const uint8Array = new Uint8Array(arrayBuffer);
      outputStream.write(uint8Array, uint8Array.length);
      outputStream.close();
      alert('文件已成功保存!');
    };
    reader.readAsArrayBuffer(blob);
  } else {
    console.log('用户取消了文件保存操作');
  }
}

// 调用示例:替换成你的下载链接和默认文件名
downloadAndSaveFile('http://example.com/download.php?myfile.pdf', 'myfile.pdf');
关键细节说明
  • XHR配置:必须把responseType设为'blob',这样XHR会直接返回Blob二进制对象,省去手动解析响应内容的麻烦。
  • XPCOM组件作用:
    • nsIFilePicker:负责唤起系统原生的文件保存对话框,让用户选择保存路径和文件名,同时支持文件类型过滤。
    • nsIFileOutputStream:Firefox底层的文件写入组件,用来将Blob的二进制内容写入本地文件,注意参数里的文件操作模式和权限设置。
  • Blob转字节数组:因为XPCOM流只接受字节数组输入,所以用FileReader把Blob转成ArrayBuffer,再转成Uint8Array后写入流。
注意事项
  • 这段代码必须放在Firefox扩展的Chrome上下文(比如overlay脚本、content script)中运行,普通网页没有XPCOM组件的访问权限。
  • Firefox 45属于旧版XUL扩展体系,如果你是开发WebExtensions的话这套代码不适用,但你明确针对Firefox 45扩展,所以完全兼容。
  • 示例里加了基础的错误处理,你可以根据需求扩展(比如处理文件写入失败、重复文件名提示等)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:47:16