下载带前缀点的文件时文件名被修改的问题排查
下载带前缀点的文件时文件名被篡改的问题
多数文件能正常下载,但下载名称以.(点)开头的文件时,前缀点会被移除,还自动添加.txt后缀——比如.bashrc下载后变成bashrc.txt。
服务器响应情况
从截图可见,服务器返回的响应未正确设置Content-Disposition头指定文件名,且Content-Type默认是text/plain类型。
你的代码
await downloadFileFromServerAPI({ ...details, connectionId: connectionId }).then((res) => { debugger; const downloadFileURL = window.URL.createObjectURL(new Blob([res])); const downloadFileLink = document.createElement('a'); downloadFileLink.href = downloadFileURL; downloadFileLink.setAttribute('download', details.name); downloadFileLink.click(); setTimeout(() => { document.body.removeChild(downloadFileLink); }, 2000); });
问题原因
- Blob未指定MIME类型:创建Blob时没传类型参数,浏览器默认将其识别为
text/plain,会自动给这类文件强制添加.txt后缀。 - 浏览器对隐藏文件名的处理:对于
text/plain类型的文件,部分浏览器会自动移除文件名开头的.(认为这是系统隐藏文件的标识),进一步篡改了文件名。
解决方案
1. 给Blob指定正确的MIME类型
从服务器响应中获取文件的Content-Type,或者根据文件名后缀推断类型,创建Blob时传入类型参数:
await downloadFileFromServerAPI({ ...details, connectionId: connectionId }).then((res) => { // 优先用服务器返回的Content-Type, fallback到二进制流类型 const mimeType = res.headers?.['Content-Type'] || 'application/octet-stream'; // 注意:如果res是完整响应对象,需取res.data作为Blob内容 const downloadFileURL = window.URL.createObjectURL(new Blob([res.data], { type: mimeType })); const downloadFileLink = document.createElement('a'); downloadFileLink.href = downloadFileURL; downloadFileLink.setAttribute('download', details.name); // 部分浏览器要求链接必须在DOM中才能触发下载 document.body.appendChild(downloadFileLink); downloadFileLink.click(); setTimeout(() => { document.body.removeChild(downloadFileLink); // 释放URL对象,避免内存泄漏 window.URL.revokeObjectURL(downloadFileURL); }, 2000); });
2. 配合服务器端设置响应头
让服务器在返回文件时添加以下响应头:
Content-Disposition: attachment; filename=".bashrc" Content-Type: text/plain # 或者对应文件的正确类型,比如application/octet-stream
明确告诉浏览器文件名和文件类型,从根源避免浏览器自动篡改文件名。
额外提示
- 务必调用
window.URL.revokeObjectURL释放创建的URL对象,否则会造成内存泄漏。 - 仅前端修改可能在部分浏览器中仍有兼容问题,服务器端配合设置响应头是更稳妥的方案。
内容的提问来源于stack exchange,提问作者Maulik Kakadiya
相关产品推荐
相关产品推荐

