Node.js后端保存PDF后无法在浏览器打开,报window is not a function错误
问题原因
Node.js控制器运行在服务器端,window是浏览器环境独有的全局对象,服务器端不存在这个对象,所以直接调用window.open()会报错。服务器与浏览器是完全分离的两个环境,后端无法直接操作客户端的浏览器窗口。
解决方法
正确的做法是后端返回PDF的可访问URL,由前端负责打开,具体步骤如下:
1. 后端修改:返回PDF的访问路径
首先确保你的frontend/public目录被配置为静态资源目录(比如用Express的express.static),让前端能直接访问里面的文件。然后修改控制器代码,保存PDF后返回对应的URL:
const fs = require('fs'); const path = require('path'); const { deliveryType, referenceNo } = req.body.datas; const config = { headers: { "Content-Type": "application/json", } }; const { data } = await axios.post(`xxxxx`, { deliveryType, referenceNo, }, config); const pdfBuffer = data.result.BarcodeZpl; // 假设这是PDF的Buffer数据 const time = Date.now(); const filename = `label${time}.pdf`; const savePath = path.join(__dirname, 'frontend/public/pdfs', filename); // 保存PDF到本地 fs.writeFileSync(savePath, pdfBuffer); // 生成前端可访问的URL(假设服务器静态资源根目录对应frontend/public) const pdfUrl = `/pdfs/${filename}`; // 返回URL给前端 res.status(201).json({ message: 'success', pdfUrl: pdfUrl });
2. 前端修改:接收URL并打开
前端在请求成功后,拿到返回的pdfUrl,用window.open()打开:
// 假设前端用axios请求 axios.post('/your-controller-path', { datas: { deliveryType, referenceNo } }) .then(response => { // 在新窗口打开PDF window.open(response.data.pdfUrl, '_blank'); }) .catch(err => { console.error(err); });
补充说明
- 若还未配置静态资源,在Express中需要添加:
app.use(express.static(path.join(__dirname, 'frontend/public'))); - 不要尝试在后端直接操作浏览器,这违背前后端分离的架构逻辑,也无法实现。
内容的提问来源于stack exchange,提问作者322quick1
相关产品推荐
相关产品推荐

