joken-前端工程师

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: :: :: 管理 ::

在使用 Axios 下载文件时,默认情况下,Blob 数据不会包含文件名(因为 Blob 本身没有 name 属性)。但你可以通过以下方法获取文件名:


  1. 从响应头 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);
});

  1. 从 URL 路径推断文件名(备用方案)
    如果服务器未返回 Content-Disposition,可以尝试从 URL 中提取文件名(不推荐,可靠性低):
const url = '/download/file/example.pdf';
const fileName = url.split('/').pop(); // "example.pdf"

  1. 将 Blob 转换为 File(需手动指定文件名)
    如果需要 File 对象(例如上传到其他接口),可以手动添加文件名:
const blob = response.data;
const file = new File(blob, fileName, { type: blob.type }); // 使用解析出的文件名

注意事项

  1. 跨域问题:

    • 如果请求跨域,需确保服务器返回 Access-Control-Expose-Headers: Content-Disposition,否则前端无法读取 Content-Disposition 头。
  2. 编码问题:

    • 如果文件名包含中文或特殊字符,服务器应使用 filename*=UTF-8'' 格式(如 filename*=UTF-8''%E6%96%87%E4%BB%B6.txt),前端需解码:
      javascript
      decodeURIComponent(fileNameMatch1);
  3. 默认文件名:

    • 始终提供默认文件名(如 unknown.bin),避免解析失败时出错。

总结
方法 适用场景 可靠性

ContentDisposition 响应头 服务器支持时(推荐) ⭐⭐⭐⭐
URL 路径推断 无响应头时的备用方案 ⭐⭐
手动指定文件名 需要 File 对象时 ⭐⭐⭐

通过正确解析响应头,可以可靠地获取文件名并实现文件下载功能。

posted on 2025-06-10 22:51  joken1310  阅读(278)  评论(0)    收藏  举报