You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从后端发送文件至浏览器下载?Blob体积异常问题求助

问题原因

浏览器前端请求时,请求库(比如axios)默认会把响应解析成UTF-8字符串,二进制文件(图片、文档等)被转成字符串后再生成Blob,会出现编码错误,导致文件体积变大、内容损坏,无法正常打开。而Postman/Thunder Client会自动识别并处理二进制响应,所以能正常保存文件。


解决方案

1. 前端修复(核心)

必须告诉请求库不要解析响应,直接返回二进制数据。以axios为例,修改请求配置并调整前端下载逻辑:

// 先修改downloadFile的请求配置
const downloadFile = (id: string) => {
  return axios.get(`/files/download/${id}`, {
    responseType: 'blob' // 关键:指定响应类型为Blob,避免字符串解析
  });
};

async downloadFiles(id: string) {
  try {
    const { data, headers } = await downloadFile(id);
    const url = window.URL.createObjectURL(data);
    const link = document.createElement('a');
    link.href = url;
    
    // 从响应头获取文件名,避免前端硬编码
    const contentDisposition = headers['content-disposition'];
    let filename = '未知文件';
    if (contentDisposition) {
      const match = contentDisposition.match(/filename="?([^"]+)"?/);
      filename = match?.[1] || filename;
    }
    link.setAttribute('download', filename);
    
    document.body.appendChild(link);
    link.click();
    link.remove();
    window.URL.revokeObjectURL(url); // 释放内存,避免泄漏
  } catch (error) {
    console.error('下载失败:', error);
  }
}

2. 后端优化(可选但推荐)

  • 不要把整个文件读进内存(fs.readFileSync),直接用文件流传输,降低大文件场景下的内存占用
  • 对文件名编码,避免中文/特殊字符导致的乱码问题
router.get('/files/download/:id', async (req, res) => {
  try {
    const { id } = req.params;
    const file = await FileArea.findById(id);
    if (!file) {
      return res.status(404).send('File not found');
    }
    if (fs.existsSync(file.path)) {
      // 直接创建文件读取流,无需预加载文件内容
      const readStream = fs.createReadStream(file.path);
      // 编码文件名,兼容中文
      res.set('Content-Disposition', `attachment; filename="${encodeURIComponent(file.name)}"`);
      res.set('Content-Type', file.type);
      
      readStream.pipe(res);
      // 监听流错误,避免崩溃
      readStream.on('error', () => res.status(500).send('Internal server error'));
    } else {
      return res.status(404).send('File not found');
    }
  } catch (error) {
    return res.status(500).send('Internal server error');
  }
});

内容的提问来源于stack exchange,提问作者rmb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 06:10:39