[英]Node/Express: Why can't you pass res to a helper function (e.g. for validation) and avoid ERR_HTTP_HEADERS_SENT?
我有一个使用 Node (v.18.2) 和 Express (v. 4.18) 构建的 web 应用程序。 用户可以发送 POST 请求,我会在他们到达时进行验证; 如果用户犯了错误,我会发回一条错误消息,以便用户知道出了什么问题。
在这样做时,我想添加一些辅助函数,因为这些检查会在许多端点中发生,并且我想保持我的代码干燥,例如用户是否发送了正确类型的输入,她的帐户中是否有足够的信用, 等等。
我的意图是将res
function 传递给这些请求,以允许他们向用户发回响应。 但是,代码继续运行,遇到另一个res.json
,这当然会触发错误[ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
。
这是我从代码库中提取的简化示例:
app.post("/demonstration", async (req, res) => {
const user = req.body.user;
// user = {id: 123, credits: 0}
// Validation - Check if user has enough credits
await checkCredits(user, res);
res.json({ result: "success" });
return;
});
function 定义为:
async function checkCredits(user, res) {
const credits = user.credits;
if (credits <= 0) {
res.json({ result: "failure" });
return;
}
}
基于这篇文章的一个直接解决方案是让checkCredits
返回 true/false,然后在主体的 if/else 语句中使用它来决定是发送成功还是失败响应,如下所示(有效):
app.post("/demonstration", async (req, res) => {
const user = req.body.user;
// user = {id: 123, credits: 0}
// Validation - Check if user has enough credits
const hasEnoughCredits = await checkCredits(user); // Returns true if user has enough credits
if (!hasEnoughCredits) {
res.json({ result: "failure" });
return;
}
res.json({ result: "success" });
return;
});
我只是不明白(A)为什么res
不能被传递(在第一个例子中)和/或(B)为什么res.json({})
和return
不足以终止连接并停止尝试发回额外的回复。
在我继续之前,我只想了解这里发生了什么,所以如果有人有任何提示或进一步阅读的链接(例如我在阅读此内容时错过的文档或 SO 帖子),我将非常感谢您的见解。
在向用户报告错误后让您的辅助函数返回false
(如果没有错误,则返回true
)并在调用它们时检查返回值:
async function checkCredits(user, res) {
const credits = user.credits;
if (credits <= 0) {
res.json({ result: "failure" });
return false;
}
return true;
}
app.post("/demonstration", async (req, res) => {
const user = req.body.user;
if (!(await checkCredits(user, res))) return;
res.json({ result: "success" });
return;
});
一个 function 中的返回仅终止 function,它不终止请求处理。
(A) 为什么 res 不能被传递(在第一个例子中)
它可以。 并且是。
(B) 为什么 res.json({}) 和 return 不足以终止连接并停止尝试发回额外的响应。
return
只会停止当前的 function。
如果每次 function 一直停止return
调用堆栈,这将不是很有用。 const foo = bar();
将存在 function 在您可以对foo
做任何事情之前!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.