如何用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
相关产品推荐
相关产品推荐

