Node.js API生成PDF后,如何在浏览器打开接收的ReadableStream
解决Node.js API生成PDF后在浏览器中打开ReadableStream的问题
一、后端响应头调整
当前后端设置的Content-Disposition为attachment,会触发浏览器下载行为。要实现浏览器内打开PDF,需将该头改为inline,告诉浏览器以内联方式渲染文件:
修改app.js中响应头部分:
app.post("/pdf", async (req, res) => { try { const parameterData = req.body await pdf(parameterData); const data = fs.createReadStream('./test/output.pdf'); const stat = fs.statSync('./test/output.pdf'); res.setHeader('Content-Length', stat.size); res.setHeader('Content-Type', 'application/pdf'); // 把attachment改为inline,触发浏览器内联显示 res.setHeader('Content-Disposition', 'inline; filename=output.pdf'); data.pipe(res); } catch (err) { // 增加错误捕获,返回友好提示 res.status(500).json({ error: 'PDF生成失败', details: err.message }); } })
二、前端处理ReadableStream
浏览器通过fetch接收到的res.body是ReadableStream,需将其转换为Blob对象,再通过临时URL在浏览器中打开:
修改index.html中的脚本部分:
<script> const paramData = { // 填入你的参数 } document.querySelector('button') .addEventListener('click', (e) => { fetch('/pdf', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(paramData) }) .then(async (res) => { if (!res.ok) throw new Error(`请求失败:${res.status}`); // 将ReadableStream转换为Blob对象 const pdfBlob = await res.blob(); // 创建临时URL const pdfUrl = URL.createObjectURL(pdfBlob); // 在新窗口打开PDF const pdfWindow = window.open(pdfUrl); // 可选:窗口关闭后释放临时URL资源 pdfWindow?.addEventListener('unload', () => { URL.revokeObjectURL(pdfUrl); }); }) .catch(err => console.error('处理PDF出错:', err)); }); </script>
可选:在当前页面嵌入PDF
如果不想新开窗口,也可以通过iframe在当前页面嵌入PDF:
// 替换window.open部分的代码 const iframe = document.createElement('iframe'); iframe.src = pdfUrl; iframe.style.width = '100%'; iframe.style.height = '800px'; iframe.style.border = 'none'; document.body.appendChild(iframe); // 加载完成后释放临时URL iframe.addEventListener('load', () => { URL.revokeObjectURL(pdfUrl); });
内容的提问来源于stack exchange,提问作者Ricardo Hernández
相关产品推荐
相关产品推荐

