Express POST请求res.send()返回内容浏览器未生效问题
问题根源
两个低级错误,改完就好:
- 后端POST路由把响应逻辑写在了
data事件回调里,没有等请求体完全接收就返回,很容易触发响应异常;首页GET路由里多余的close事件监听也会干扰正常响应流程 - 前端fetch没有解析响应体,直接打印Response对象,你看不到实际返回的文本内容,误以为res.send没生效
具体修改方法
第一步:修改后端APP.js
首先删掉首页路由里多余的req.on("close",() => res.end());,res.sendFile会自动处理响应结束,不需要手动加这行。
然后直接用Express自带的JSON解析中间件,不用自己手动监听data事件拼请求体,省事还不容易错。改完的完整代码:
const exp = require("express"); const app = exp(); // 开启JSON请求体自动解析,解析完的内容会直接放到req.body里 app.use(exp.json()); app.get("/",(req,res)=>{ res.sendFile(__dirname+"/index.html"); }); app.get("/index.js",(req,res)=>{ res.sendFile(__dirname+"/index.js"); }); app.post("/",(req,res) => { console.log(req.body.message); res.send(req.body.message); }); app.listen(3000,()=>{ console.log("server started at 3000"); });
*如果你想搞懂不用中间件的原生写法,要记住data事件会把大请求拆成多个数据块传输,必须等end事件触发,拼完所有数据再处理返回,写法如下,新手直接用上面的中间件方案就行:
app.post("/",(req,res) => { let rawBody = ''; req.on('data', (chunk) => { rawBody += chunk.toString(); }); req.on('end', () => { const postData = JSON.parse(rawBody); console.log(postData.message); res.send(postData.message); }) });
第二步:修改前端INDEX.js
fetch请求返回的第一个then参数是Response对象,不是服务端返回的实际内容,必须调用对应的解析方法拿到内容。你返回的是纯文本,调用.text()解析即可。改完的代码:
let obj = { message: "hello world" }; document.querySelector(".hw").addEventListener("click",()=>{ fetch("/",{ method: "POST", headers: { 'Content-Type':'application/json', }, body: JSON.stringify(obj), }) .then(res => res.text()) // 解析响应体为文本 .then(data => { console.log(data); // 这里就能拿到服务端返回的hello world了 // 要把内容显示到页面,直接在这里写DOM操作逻辑就行 }) .catch(err => console.log(err)); });
验证
改完代码重启Node服务,点击按钮后:
- 后端控制台正常打印
hello world - 浏览器控制台也会打印
hello world,浏览器Network面板的POST请求响应里也能看到对应返回内容
内容的提问来源于stack exchange,提问作者ruchikxxii
相关产品推荐
相关产品推荐

