簡體   English   中英

使用nodejs mysql將標頭發送到客戶端后無法設置標頭

[英]Cannot set headers after they are sent to the client using nodejs mysql

我試圖做的是編寫一個語句來檢查用戶注冊時電子郵件是否存在於我的 mysql 數據庫中。 在郵遞員中,它向我發送了“用戶已被占用”的正確錯誤消息,但是服務器隨后崩潰並顯示“在將標頭發送到客戶端后無法設置標頭”。 我讀過類似的帖子,但沒有幫助。

//The following code is in my user.service.js file:

const pool = require("../../config/database");

module.exports = {

  //Create new user
  createUser: (data, callBack) =>{
    pool.query(
      `insert into registration(name, email, password, confirm_password)
              values(?,?,?,?)`,
    [
      data.name,
      data.email,
      data.password,
      data.confirm_password
    ],
    (error, results, fields) =>{
      if(error){
        return callBack(error);
      }
      return callBack(null, results);
    }
    );
  }
}

//以下代碼在我的user.controller.js文件中:

const {
  createUser,
} = require("./user.service");
const pool = require("../../config/database");


module.exports = {
  
  createUser: (req, res) =>{
    const body = req.body;
    const salt = genSaltSync(10);
  pool.query('SELECT email FROM registration WHERE email = ?', [body.email], (error, results) =>{
    if(error){
      console.log(error);
    }
    if(results.length > 0){
      return res.status(400).json({
        message: 'User already taken'
      })
    }
  })
    createUser(body, (err, results) => {
      if(err){
        console.log(err);
        return res.status(500).json({
          success:0,
          message:"Error in database connection"
        });
      }
      return res.status(200).json({
        success: 1,
        message: `User ${results.insertId} signed up successfully`,
        data: results
      });
    });
  }

}

//以下代碼來自user.router.js文件:

const {
  createUser,
} = require("./user.controller");
const router = require("express").Router();

router.post("/signup", createUser);

module.exports = router;

在對 post 請求執行的createUser函數中,您正在做兩件事。 首先,您檢查是否存在使用提供的電子郵件的用戶,然后創建一個用戶。 但是,這些函數不是連續執行的,而是同時運行的,因此會產生競爭條件。

所以繼續你的例子,如果電子郵件檢查查詢SELECT email FROM registration WHERE email = ? 速度更快並且用戶已經存在,它將響應:

  return res.status(400).json({
    message: 'User already taken'
  })

但是createUser函數(如下)仍在運行,一旦完成,它也會嘗試發送響應。 因此,您會在控制台中看到應用程序崩潰,即使在郵遞員中您可以看到說明用戶已經存在的響應。

為了修復此錯誤,您應該僅在提供給電子郵件檢查查詢的回調中的results.length0時才執行createUser函數,如下所示:

createUser: (req, res) => {
    const body = req.body;
    const salt = genSaltSync(10);
  pool.query('SELECT email FROM registration WHERE email = ?', [body.email], (error, results) =>{
    if(error){
      console.log(error);
    }

    if(results.length > 0){
      return res.status(400).json({
        message: 'User already taken'
      })
    }

    createUser(body, (err, results) => {
      if(err){
        console.log(err);
        return res.status(500).json({
          success:0,
          message:"Error in database connection"
        });
      }
      return res.status(200).json({
        success: 1,
        message: `User ${results.insertId} signed up successfully`,
        data: results
      });
    });
  })
}

現在,您僅在提供電子郵件的用戶不存在時才執行createUser函數,這有效地消除了兩個函數之間的競爭條件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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