Node.js+Express中间件未执行第二个if语句就调用next()问题排查
问题根源分析
- 原始代码的核心问题:校验失败调用
res.json()返回响应后,没有终止当前中间件的执行逻辑,代码会继续走完第二个if判断,最后还会调用next()进入后续中间件。如果后续中间件也操作了响应,会直接抛出「Cannot set headers after they are sent to the client」的报错,也会出现逻辑提前执行的问题。 - 修改后代码的问题:return的位置完全错误,只要走完手机号判断的任意分支(有手机号走if分支,没手机号走else分支),都会直接return终止函数执行,后续的邮箱校验逻辑永远不会触发,且大部分分支既没有返回响应也没有调用
next(),客户端自然收不到任何响应,只会等待超时。
正确实现代码
所有校验失败、已经调用res.json()返回错误响应的位置加return终止执行,校验通过的分支不要加return,保证能走到后续校验逻辑,所有校验全部通过后再调用next():
app.use((req: Request, res: Response, next: express.NextFunction) => { const email: string = req.body.email; const phoneNum: string = req.body.phone; console.log(phoneNum); // 手机号校验 if (phoneNum) { if (!phone(phoneNum).isValid) { res.json({ message: "invalid phone format. Expecting format like: 8001234567", }); return; // 发完错误响应直接终止,不走后续逻辑 } req.body.phone = phone(phoneNum).phoneNumber; } // 邮箱校验 if (email) { if (!EmailValidator.validate(email)) { res.json({ message: "invalid email format. Expecting format like: name@domain.com", }); return; // 发完错误响应直接终止,不走后续逻辑 } } // 所有校验都通过,进入下一个中间件 next(); });
核心注意点
- Express中只要调用了
res.json()/res.send()/res.end()等返回响应的方法后,必须手动加return终止当前中间件的剩余代码执行,否则逻辑会继续往下走 - 只有校验全部通过的场景才需要调用
next(),不能在校验过程中随意调用 - 不要在校验通过的分支加无意义的return,会阻断后续的校验逻辑执行
内容的提问来源于stack exchange,提问作者Jacob Miller
相关产品推荐
相关产品推荐

