Node.js接口返回PDF前端请求报204无法在浏览器打开问题求解
问题根因分析
- 后端错误使用
open依赖:open包的作用是在服务端本地操作系统打开指定文件/链接,你传入res.send()的返回值(响应对象)不符合入参要求,直接触发类型报错。服务端触发未捕获的Promise异常后,请求响应流程中断,所以前端拿到204无内容的状态码。 - 前端代码存在语法错误:
return后直接换行触发JS自动分号插入机制,fetch请求根本没有执行。 - 前端没有处理接口返回的PDF流:即使接口请求成功,也没有把返回的二进制流转为可预览的PDF资源。
- 后端错误处理逻辑缺失:读取文件出错时仅打印日志,没有给前端返回错误响应,会导致前端请求超时或无响应。
修复方案
1. 后端代码修复
直接删掉open(file)这行多余的代码,补全错误处理逻辑,可选添加预览用的响应头:
app.post('/readFile/uploads/:filename', function (req, res) { res.setHeader("Access-Control-Allow-Origin", "*") res.setHeader('Content-Type', 'application/pdf'); // inline表示浏览器直接预览,改为attachment会触发下载 res.setHeader('Content-Disposition', 'inline; filename=' + req.params.filename); console.log("inside Download", req.params.filename) fs.readFile(`./uploads/${req.params.filename}`, function (err, filecontent) { if (err){ console.log(err.message) // 出错返回404状态码 return res.status(404).send('文件不存在') } console.log("读取文件成功", filecontent) // 直接返回文件内容即可,不需要调用open res.send(filecontent) }) });
如果不需要做额外权限校验,也可以把POST请求改为GET请求,更符合资源获取的语义,前端可以直接用window.open打开链接预览,不需要额外写fetch逻辑。
2. 前端代码修复
修正语法错误,添加PDF流处理逻辑,请求成功后转为blob打开新标签页预览:
const openPdf = async (imagename) => { console.log("打开PDF", imagename) try { const response = await fetch(`http://localhost:8080/readFile/uploads/${imagename}`,{ method:"POST", headers: { Accept: "application/pdf", }, }) // 把返回的二进制流转为blob对象 const blob = await response.blob() // 生成临时blob访问链接 const pdfUrl = window.URL.createObjectURL(blob) // 新标签页打开预览PDF window.open(pdfUrl, '_blank') // 手动释放blob资源避免内存泄漏 window.URL.revokeObjectURL(pdfUrl) } catch (e) { console.error('打开PDF失败', e) } }
如果后端改为GET接口,前端可以直接简化为一行代码:
const openPdf = (imagename) => window.open(`http://localhost:8080/readFile/uploads/${imagename}`, '_blank')
内容的提问来源于stack exchange,提问作者Samad ullah
相关产品推荐
相关产品推荐

