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

使用fetch方法搭配NodeJS路由时PDF无法加载的问题

问题解决:Node.js直接返回PDF流而非存储文件的正确实现

核心问题分析

你的代码存在两个关键错误,导致直接pipe PDF流无法正常工作:

  • 后端逻辑冲突:在将PDF流pipe到response后,又调用了response.send(JSON.stringify(...)),这会在PDF数据后追加JSON内容,彻底破坏PDF格式;同时响应头已设置为application/pdf,返回JSON完全不符合协议规范。
  • 前端解析错误:当前代码默认将响应解析为JSON,但后端返回PDF流时,前端需要接收Blob类型数据并处理,而非尝试解析JSON。

修正后的后端代码

移除多余的response.send()调用,确保只返回纯净的PDF流:

function _postMultiplePrint(request, response) {
  var fonts = {
        Roboto: {
          normal: 'public/fonts/OpenSans-Regular.ttf',
          bold: 'public/fonts/OpenSans-Bold.ttf',
          italics: 'public/fonts/OpenSans-Italic.ttf',
          bolditalics: 'public/fonts/OpenSans-BoldItalic.ttf'
        }
      },
      printer = new PdfPrinter(fonts),
      docDefinition, pdfDoc;

  docDefinition = {
    content: [
      {
        text: 'This paragraph fills full width, as th'
      }
    ],
    pageSize: 'A4',
    pageMargins: [72, 72],
    footer: {},
    background: {}
  };

  pdfDoc = printer.createPdfKitDocument(docDefinition);
  response.setHeader('Content-type', 'application/pdf');
  response.setHeader('Content-disposition', 'inline; filename="book.pdf"');
  // 监听PDF流结束事件,自动结束响应
  pdfDoc.on('end', () => response.end());
  pdfDoc.pipe(response);
  pdfDoc.end();
}

修正后的前端代码

修改fetch处理逻辑,接收Blob并在页面中打开PDF:

fetch(url, {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  credentials: 'same-origin',
  body: JSON.stringify({ ids: arrayIds })
}).then(function(response) {
  if (!response.ok) throw new Error('请求失败');
  return response.blob();
}).then(function(blob) {
  // 创建临时URL并在当前页面打开PDF
  const pdfUrl = URL.createObjectURL(blob);
  document.location.href = pdfUrl;
  // 可选:若在新标签页打开,可替换为下面一行,之后记得释放临时URL
  // window.open(pdfUrl, '_blank');
  // setTimeout(() => URL.revokeObjectURL(pdfUrl), 10000);
}).catch(function(error) {
  console.error('生成PDF失败:', error);
});

兼容原有reload逻辑的进阶处理

如果需要保留原有的页面刷新逻辑,可以在前端先判断响应类型,分别处理JSON和PDF流:

fetch(url, { /* 原有配置 */ })
.then(response => {
  const contentType = response.headers.get('Content-Type');
  if (contentType.includes('application/json')) {
    return response.json();
  } else if (contentType.includes('application/pdf')) {
    return response.blob();
  }
  throw new Error('未知响应类型');
})
.then(data => {
  if (typeof data === 'object' && data.reload) {
    document.location.reload();
  } else if (data instanceof Blob) {
    const pdfUrl = URL.createObjectURL(data);
    document.location.href = pdfUrl;
  }
})

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 04:21:48