抗日胜利80周年:前端下载 ‘Content-Type‘: ‘application/octet-stream‘ 的文件 多种解决方案

中国人民抗日战争暨世界反法西斯战争胜利80 周年
中国人民抗日战争暨世界反法西斯战争胜利80 周年

一、最常见方式:a 标签 + Blob

如果后端返回的是二进制数据(Blob / ArrayBuffer),我们可以把它转成 Blob 对象,然后用 URL.createObjectURL 生成下载链接。

fetch('/api/download/file', {
  method: 'GET',
  headers: {
    // 如果需要携带 token 之类的,可以加上
    'Authorization': 'Bearer xxx'
  }
})
.then(res => res.blob())  // 转换为 blob
.then(blob => {
  const url = window.URL.createObjectURL(blob); // 创建临时链接
  const a = document.createElement('a');
  a.style.display = 'none';
  a.href = url;
  a.download = 'myFile.zip';  // 下载文件名(可根据后端返回动态设置)
  document.body.appendChild(a);
  a.click();  // 触发下载
  document.body.removeChild(a);
  window.URL.revokeObjectURL(url); // 释放内存
});

👉 注意:

  • a.download 属性设置文件名,如果不写,可能会用 URL 里的名字。

  • window.URL.revokeObjectURL(url) 用于释放临时对象,避免内存泄露。


二、获取文件名(Content-Disposition)

有些后端会在响应头里加 Content-Disposition: attachment; filename="xxx.pdf",这时候可以动态解析文件名。

fetch('/api/download/file')
  .then(async res => {
    const blob = await res.blob();
    const disposition = res.headers.get('Content-Disposition');
    let filename = 'default.file';

    if (disposition && disposition.includes('filename=')) {
      filename = decodeURIComponent(
        disposition.split('filename=')[1].replace(/"/g, '')
      );
    }

    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    a.remove();
    window.URL.revokeObjectURL(url);
  });

三、使用 axios 下载二进制文件

如果用 axios,要记得设置 responseType: 'blob'

import axios from 'axios';

axios.get('/api/download/file', {
  responseType: 'blob'
}).then(res => {
  const blob = new Blob([res.data]);
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = 'download.zip';
  a.click();
  window.URL.revokeObjectURL(url);
});

四、兼容 IE 的方案(msSaveBlob)

旧版 IE/Edge 不支持 URL.createObjectURL,需要用 msSaveOrOpenBlob

if (window.navigator.msSaveOrOpenBlob) {
  // IE/Edge 专用
  window.navigator.msSaveOrOpenBlob(blob, filename);
} else {
  // 现代浏览器
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = filename;
  a.click();
  window.URL.revokeObjectURL(url);
}

五、后端直接返回下载链接(非二进制流)

如果后端直接返回一个下载 URL(不是流),最简单的就是:

window.location.href = '/api/download/file';

但缺点是:

  • 不好控制文件名

  • 不方便带自定义 header(如 token)


✅ 总结:

  1. 如果后端返回二进制流 → fetch/axios + blob + a.download

  2. 如果后端返回 Content-Disposition → 解析文件名

  3. 兼容老浏览器(IE/Edge) → msSaveOrOpenBlob

  4. 如果只是个直链 → window.location.href

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星空下的DeppBing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值