簡體   English   中英

Node/Express:為什么不能將 res 傳遞給幫助程序 function(例如用於驗證)並避免 ERR_HTTP_HEADERS_SENT?

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM