在使用 Axios 下载文件时,默认情况下,Blob 数据不会包含文件名(因为 Blob 本身没有 name 属性)。但你可以通过以下方法获取文件名:
- 从响应头
Content-Disposition提取文件名
服务器通常会在响应头Content-Disposition中返回文件名,格式如:
Content-Disposition: attachment; filename="example.pdf"
代码示例:
axios({
method: 'get',
url: '/download/file',
responseType: 'blob', // 关键:指定响应类型为 blob
}).then((response) => {
// 1. 获取 Blob 数据
const blob = new Blob(response.data);
// 2. 从响应头解析文件名
const contentDisposition = response.headers'content-disposition';
let fileName = 'default-filename.ext'; // 默认文件名(备用)
if (contentDisposition) {
// 使用正则匹配文件名(兼容带引号和不带引号的情况)
const fileNameMatch = contentDisposition.match(/filename="?(^"+)"?/);
if (fileNameMatch && fileNameMatch1) {
fileName = fileNameMatch1;
}
}
// 3. 创建下载链接
const downloadUrl = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = downloadUrl;
a.download = fileName; // 设置下载的文件名
a.click();
// 4. 释放内存
URL.revokeObjectURL(downloadUrl);
});
- 从 URL 路径推断文件名(备用方案)
如果服务器未返回Content-Disposition,可以尝试从 URL 中提取文件名(不推荐,可靠性低):
const url = '/download/file/example.pdf';
const fileName = url.split('/').pop(); // "example.pdf"
- 将 Blob 转换为 File(需手动指定文件名)
如果需要File对象(例如上传到其他接口),可以手动添加文件名:
const blob = response.data;
const file = new File(blob, fileName, { type: blob.type }); // 使用解析出的文件名
注意事项
-
跨域问题:
- 如果请求跨域,需确保服务器返回
Access-Control-Expose-Headers: Content-Disposition,否则前端无法读取Content-Disposition头。
- 如果请求跨域,需确保服务器返回
-
编码问题:
- 如果文件名包含中文或特殊字符,服务器应使用
filename*=UTF-8''格式(如filename*=UTF-8''%E6%96%87%E4%BB%B6.txt),前端需解码:
javascript
decodeURIComponent(fileNameMatch1);
- 如果文件名包含中文或特殊字符,服务器应使用
-
默认文件名:
- 始终提供默认文件名(如
unknown.bin),避免解析失败时出错。
- 始终提供默认文件名(如
总结
方法 适用场景 可靠性
ContentDisposition 响应头 服务器支持时(推荐) ⭐⭐⭐⭐
URL 路径推断 无响应头时的备用方案 ⭐⭐
手动指定文件名 需要 File 对象时 ⭐⭐⭐
通过正确解析响应头,可以可靠地获取文件名并实现文件下载功能。
前端工程师、程序员

浙公网安备 33010602011771号