You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用next()和res.send时出现ERR_HTTP_HEADERS_SENT错误求助

解决Express中的Cannot set headers after they are sent to the client错误

错误核心原因

你触发这个错误的根本问题是:在已经通过res.send()发送响应后,又调用了next()让后续中间件继续执行,而后续匹配到的中间件再次尝试给同一个请求发送响应。HTTP协议规定一个请求只能对应一次响应,重复操作响应头就会抛出ERR_HTTP_HEADERS_SENT错误。

先给你理清楚中间件和next()的基本逻辑:
Express的中间件是按注册顺序执行的处理管道,next()的作用是把当前请求传递给下一个匹配的中间件。但如果你的中间件已经完成了响应发送(比如调用res.send()/res.redirect()),就绝对不能再调用next()——此时请求-响应周期已经结束,后续中间件再操作响应对象必然出错。

你的代码问题拆解

看你写的代码:

  1. 在/add-product中间件里,你先调用res.send()返回了表单页面,随后又调用next()。这会让请求继续向下匹配后续中间件。
  2. 后续的app.use('/')会匹配所有以/开头的请求(包括/add-product),于是这个中间件又调用res.send()返回欢迎信息,导致同一个请求被发送了两次响应,直接触发错误。
  3. 另外还有个小问题:处理/product的POST请求用了app.use,但app.use会匹配所有HTTP方法(GET/POST等),应该用app.post来专门处理POST请求。

修正后的代码

const express = require('express')
const app = express()

// 必须添加这个中间件,才能解析POST表单的请求体数据
app.use(express.urlencoded({ extended: true }))

app.use('/add-product',(req,res)=>{
    console.log("This is add-product page")
    res.send("<form action='/product' method='POST'><input type='text' name='title'><button type='submit'>Submit</button></form> ")
    // 这里移除next(),因为已经发送了响应,请求周期结束
})

// 用app.post专门处理POST请求,避免GET请求误匹配
app.post('/product',(req,res)=>{
    console.log('this is product-page,提交的标题:', req.body.title)
    res.redirect('/')
})

app.use('/', (req,res)=>{
    res.send('Welcome to NodeJS')
})

app.listen(3000)

关键知识点总结

  • 每个HTTP请求只能对应一次响应,调用res.send()/res.redirect()/res.end()后,响应就彻底结束,不能再调用next()。
  • next()仅用于不结束请求的中间件(比如日志记录、权限校验中间件),做完自己的逻辑后把请求传递给下一个中间件处理。
  • 处理特定HTTP方法的路由,优先用app.get()/app.post(),而非app.use()。
  • 接收POST表单数据时,必须添加express.urlencoded()中间件,否则req.body会是undefined。

内容的提问来源于stack exchange,提问作者user19485562

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 18:09:25