[英]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.