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

Express res.download返回PDF 前端Blob下载内容为undefined排查

问题根因

故障和后端res.download逻辑无关,完全是前端Promise链式调用的写法错误导致的:
你在处理下载接口响应的第一个.then()回调里,没有返回res2.blob()的Promise结果,导致下一个.then()接收到的入参是默认的undefined,最终被写入Blob生成文件的内容就是字符串undefined,和你排查到的现象完全吻合。

错误代码片段对应位置:

// 错误写法
.then((res2) => {
    res2.blob() // 箭头函数包裹在大括号内时,没有return就会返回undefined
    // blob()本身是异步方法,返回Promise,不return的话外层拿不到解析后的Blob对象
})
.then((blob)=>{
    // 这里的blob实际是上一个回调的返回值undefined
    const newBlob = new Blob([blob]); // 把undefined转成字符串"undefined"存入文件
    // 后续下载逻辑拿到的自然是内容错误的文件
})

除此之外你的前端代码还有两个小问题:

  • 多余做了一层new Blob([blob])包装:res2.blob()本身就返回标准Blob对象,不需要重复包装
  • window.URL.revokeObjectURL传参错误:该方法需要传入之前生成的对象URL,你之前传的是Blob对象,会导致临时URL无法被释放,造成内存泄漏
修复代码

前端下载逻辑修正

把前端下载部分的代码替换为以下内容即可解决核心问题:

fetch(downloadUrl, {
    method: "POST",
    headers: {
        'Content-Type': 'application/json',
    },
    body: dataString,
})
.then(res2 => {
    if (!res2.ok) throw new Error('下载请求异常');
    return res2.blob(); // 必须return,把Blob结果传递给下一个then链
})
.then(blob => {
    const objectUrl = window.URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = objectUrl;
    link.download = 'certificate.pdf';
    document.body.appendChild(link);
    link.click();
    link.remove();
    window.URL.revokeObjectURL(objectUrl); // 传入生成的临时URL释放内存
})
.catch(err => {
    console.error('证书下载失败:', err);
    alert('证书下载出错,请重试');
})

后端逻辑优化(非必须,建议补充)

你当前后端代码没有处理PDF生成失败、文件发送失败的场景,出错时前端会一直等待无响应,建议补充错误返回:

const getCertificatePDF = (name, validValuesData, validValuesQty, response) => {
    // ... 省略前置逻辑
    pdf.create(document, options)
        .then(res => {
            const filePath = path.join(__dirname, 'certificate.pdf');
            response.download(filePath, "certificate.pdf", err => {
                if (err) {
                    console.error('文件发送失败:', err);
                    response.status(500).send('下载失败');
                }
            });
        })
        .catch(error => {
            console.error('PDF生成失败:', error);
            response.status(500).send('证书生成失败');
        });
}
验证方法

修复后重新测试:

  1. 下载得到的PDF文件大小和服务器本地生成的certificate.pdf大小完全一致
  2. 打开文件可以正常显示证书内容,不会再出现仅包含undefined的情况
  3. 控制台无请求报错

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.03 01:57:26