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

Express.js跨域URL强制下载PDF时下载文件为0字节问题求解

问题原因

  • 你拿到的0字节文件是因为当前代码只设置了下载相关的HTTP响应头,没有将远程PDF的实际内容写入响应体,响应内容为空所以生成的文件大小为0。
  • res.attachment()方法的作用仅为设置Content-Disposition响应头,参数仅支持传入本地文件名用于指定浏览器下载时的默认文件名,不支持传入远程URL自动拉取对应资源内容。

解决方案

你的业务场景可以通过服务端代理中转实现任意跨域PDF的强制下载,不需要将文件存储到本地服务器,直接通过流转发即可,参考实现代码如下:

服务端实现(Express)

首先安装依赖npm install node-fetch,然后修改接口逻辑:

const fetch = require('node-fetch');

app.get("/download", async (req, res) => {
  try {
    // 从请求参数获取用户提交的远程PDF地址,实际使用请加安全校验
    const remotePdfUrl = req.query.pdfUrl;
    // 请求远程PDF资源
    const remoteResponse = await fetch(remotePdfUrl);
    if (!remoteResponse.ok) {
      return res.status(remoteResponse.status).send('远程PDF资源访问失败');
    }
    // 设置下载响应头
    res.type('application/octet-stream');
    // 可自定义下载的默认文件名,也可以从远程响应头提取原始文件名
    res.attachment('target.pdf');
    // 直接将远程资源流转发给前端响应,不占用服务端磁盘存储
    remoteResponse.body.pipe(res);
  } catch (error) {
    res.status(500).send('下载处理失败:' + error.message);
  }
});

前端调用调整

将需要下载的PDF地址作为参数传递给下载接口即可:

<a class="a-very-big-button" href="/download?pdfUrl=https://cross-origin-domain-name.com/downloads/filename.pdf">Download PDF</a>

注意事项

  • 必须增加安全校验逻辑:比如限制可访问的远程域名白名单、增加请求签名校验,避免接口被恶意滥用作为公开代理
  • 如果远程资源服务器有反爬限制,可在服务端请求远程资源时补充User-Agent、Referer等请求头模拟正常浏览器访问
  • 流式转发的方式不会占用太多服务端内存,支持大体积PDF文件下载

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 09:12:02