JavaScript使用new Blob下载文件时能否修改blob:file://格式的ID标识?
问题解答
原有Blob下载方案的问题排查
你的原有代码存在一个冗余操作:调用了两次URL.createObjectURL(),第一次生成的url变量和给a.href赋值的不是同一个对象,虽然这不会直接导致文件名失效,但属于不规范写法,修正后的浏览器通用版本如下:
function download_as_txt(options) { const file = new Blob([options.data.toString()], { type: options.type }); const url = URL.createObjectURL(file); const a = document.createElement("a"); a.href = url; // 直接复用已生成的url a.download = options.name; document.body.appendChild(a); a.click(); document.body.removeChild(a); window.URL.revokeObjectURL(url); };
普通浏览器环境下上述代码可以正常识别download属性指定的文件名,你遇到的命名不生效问题是Electron的file协议场景下的特有表现:Electron对本地file协议的资源访问做了安全限制,a标签的download属性优先级会被内置的下载逻辑覆盖,才会出现blob:file:///*的默认标识。
Electron环境的最优实现方案
你找到的dialog.showOpenDialog + fs.writeFile方案是Electron场景下的标准实现,完全符合你需要的「用户自主选目录、自动写入、完成提示」的需求,更完善的实现示例参考:
const { dialog } = require('@electron/remote'); const fs = require('fs/promises'); const path = require('path'); async function download_as_txt(options) { // 弹出目录选择框 const selectResult = await dialog.showOpenDialog({ properties: ['openDirectory'], title: '选择导出目录' }); if (selectResult.canceled) return; // 用户取消选择直接返回 const savePath = path.join(selectResult.filePaths[0], options.name); try { await fs.writeFile(savePath, options.data.toString()); alertify.alert('导出成功', `文件已保存至:${savePath}`); } catch (err) { alertify.alert('导出失败', `写入文件出错:${err.message}`); } }
这个方案不需要操作DOM生成临时链接,也不会出现文件名异常问题,稳定性比Blob下载方案更高。
内容的提问来源于stack exchange,提问作者Josh Celnik
相关产品推荐
相关产品推荐

