You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让浏览器从Node.js服务器在线显示PDF而非下载?

如何让浏览器从Node.js服务器在线显示PDF文件而非直接下载?

我来帮你排查这个问题——你的代码里有几个小细节导致浏览器直接下载PDF而不是在线预览,咱们一步步修正:

问题分析

你的代码存在两个关键问题:

  1. 同时将PDF流写入本地文件和响应对象时,流的处理顺序可能导致浏览器无法及时识别可预览的PDF数据
  2. Content-Disposition头的写法不够明确,部分浏览器会因为缺少文件名信息触发下载

修正后的代码

const path = require('path');
const PDFDocument = require('pdfkit');
const fs = require('fs');

const fileName = 'file.pdf'; 
const filePath = path.join('data', fileName); 

const pdfDoc = new PDFDocument(); 

// 明确设置Content-Disposition为inline,同时指定文件名
res.setHeader('Content-Disposition', `inline; filename="${fileName}"`);
// 确保Content-Type正确设置为PDF类型
res.setHeader('Content-Type', 'application/pdf');

// 优先将PDF流pipe到响应对象,保证浏览器实时接收数据
pdfDoc.pipe(res);

// 如果需要保存文件到本地,再pipe到文件流(顺序很重要)
pdfDoc.pipe(fs.createWriteStream(filePath));

// 编写PDF内容
pdfDoc.fontSize(26).text('Hello');
// 结束PDF文档,不需要传入空字符串
pdfDoc.end();

关键细节说明

  • Content-Disposition头优化:必须明确指定inline,同时附加filename参数。这样浏览器会优先尝试在线渲染PDF,即便预览失败也能正确显示文件名供下载。仅写inline可能会被部分浏览器误判为需要下载的文件。
  • 流的pipe顺序:先把PDF流导向响应对象res,确保浏览器能及时获取到PDF数据。如果先写入本地文件,可能会导致响应延迟,触发浏览器的下载逻辑。
  • 避免多余的end参数pdfDoc.end('')中的空字符串会在PDF末尾添加无效内容,可能导致PDF损坏无法预览,直接调用pdfDoc.end()即可。

额外排查点

如果还是无法在线预览,可以检查:

  • 浏览器是否支持PDF在线预览(现代浏览器默认都支持,旧版本可能需要插件)
  • 是否有其他中间件或代码覆盖了响应头(比如某些框架会自动设置Content-Disposition: attachment
  • curl -I http://你的服务器地址查看响应头,确认Content-Typeapplication/pdfContent-Dispositioninline; filename="file.pdf"

内容的提问来源于stack exchange,提问作者M. Hagos

火山引擎 最新活动