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

SpringBoot生成PDF无法在浏览器下载的问题求助

问题分析与解决方案

核心原因:浏览器通过AJAX/fetch/axios这类脚本发起的请求获取PDF时,不会自动触发下载弹窗——这类请求的响应会直接返回给脚本,浏览器默认不会解析Content-Disposition: attachment头,这就是你看到Chrome显示PDF源码的原因。而Postman能正常下载,是因为它会自动识别并处理这个响应头。

以下是两种可行的解决方式:


方案1:前端手动处理响应内容(推荐)

通过脚本将后端返回的Blob数据转换成可下载的链接,手动触发下载:

Fetch API 示例

document.getElementById('downloadBtn').addEventListener('click', async () => {
  const reportId = '目标报表ID';
  try {
    const res = await fetch(`/download/generateReport/${reportId}`, {
      method: 'POST',
      // 若需携带token等请求头,自行添加
      headers: { 'Authorization': 'Bearer ' + yourToken }
    });
    const blob = await res.blob();
    const downloadUrl = window.URL.createObjectURL(blob);
    
    // 创建临时a标签触发下载
    const a = document.createElement('a');
    a.href = downloadUrl;
    // 从响应头解析文件名(也可直接指定)
    const disposition = res.headers.get('Content-Disposition');
    a.download = disposition?.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1].replace(/['"]/g, '') || 'FavoriteReport.pdf';
    
    document.body.appendChild(a);
    a.click();
    // 清理资源
    window.URL.revokeObjectURL(downloadUrl);
    document.body.removeChild(a);
  } catch (err) {
    console.error('下载失败:', err);
  }
});

Axios 示例

axios.post(`/download/generateReport/${reportId}`, {}, {
  responseType: 'blob' // 必须设置,否则会拿到乱码文本
})
.then(res => {
  const blob = new Blob([res.data], { type: 'application/pdf' });
  const downloadUrl = window.URL.createObjectURL(blob);
  
  const a = document.createElement('a');
  a.href = downloadUrl;
  const disposition = res.headers['content-disposition'];
  a.download = disposition?.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/)[1].replace(/['"]/g, '') || 'FavoriteReport.pdf';
  
  document.body.appendChild(a);
  a.click();
  window.URL.revokeObjectURL(downloadUrl);
  document.body.removeChild(a);
})
.catch(err => console.error('下载失败:', err));

方案2:用普通表单提交(无需前端脚本)

如果不想修改前端脚本逻辑,可让前端通过表单POST提交请求,浏览器会自动解析Content-Disposition头并触发下载:

<form action="/download/generateReport/目标报表ID" method="POST">
  <!-- 若需携带额外参数,添加hidden输入框 -->
  <button type="submit">下载报表</button>
</form>

后端代码验证

你的后端代码配置本身没有问题:

  • produces = "application/pdf"确保了响应Content-Type正确
  • Content-Disposition: attachment头设置正确
  • Access-Control-Expose-Headers: *允许前端读取响应头(包含Content-Disposition)

只需配合前端的请求方式调整即可解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:52:48