簡體   English   中英

Node.js MySQL ERR_HTTP_HEADERS_SENT

[英]Node.js MySQL ERR_HTTP_HEADERS_SENT

這是有問題的 function:

castVote: function (req, res, ip, mysql) {
    // POST return codes
    const ALREADY_VOTED = '100';
    const SUCCESS = '200';
    const FAILURE = '300';

    // Create connection to db
    // Keep connection while the client is connected
    var con = mysql.createConnection({
        host: sqlHOST,
        user: sqlUSER,
        password: sqlPASS,
        database: dbNAME
    });

    // Connect to db
    con.connect(function (err) {
        // MySQL error, return
        if (err) {
            res.send(FAILURE);
            return;
        }
    });

    // Get link voted for
    var link = req.body.song_voted;

    // Check if user has already voted
    con.query(`SELECT * FROM VotedUsers WHERE ip = '${ip}'`, function (err, result, fields) {
        if (err) {
            res.send(FAILURE);
            return;
        }

        // User hasn't voted
        if (!result.length) {
            // Cast vote here
            // ...
            // Add user's IP to voted list
            con.query(`INSERT INTO VotedUsers (ip) VALUES ('${ip}')`, function (err, result) {
                if (err) {
                    res.send(FAILURE);
                    return;
                }
            });

            res.send(SUCCESS);
            return;
        }
        // User already voted
        else {
            res.send(ALREADY_VOTED);
            return;
        }
    });
}

我這樣調用 function,每次用戶點擊一個按鈕

mysql_backend.castVote(req, res, uipv4, mysql);

mysql是mysql模塊。uipv4是用戶的ip)。

每次我單擊所述按鈕時,這是錯誤 output:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

我有兩個問題:

  1. 我的代碼有什么問題?
  2. 有沒有更好的方法來管理每個客戶端的 mysql 連接(每次用戶單擊按鈕時都不會打開一個新連接)

1.你的代碼有什么問題

我可以看到一些事情。 首先,最明顯的問題是您的con.connectcon.query函數。 您沒有正確實施它們。 con.connect接受一個回調,一旦你創建了一個連接,你的所有實現都應該在即你所有的查詢邏輯中。

無論如何,不需要con.connect function。 您可以刪除它,因為con.query將為您創建一個連接。

其次,這會導致您看到的錯誤。 您需要檢查您的應用程序以確保每個請求只調用一次res.send (或等效)。

因此,例如,這將引發您看到的錯誤。

// User hasn't voted
if (!result.length) {
    // Cast vote here
    // ...
    // Add user's IP to voted list
    con.query(`INSERT INTO VotedUsers (ip) VALUES ('${ip}')`, function (err, result) {
        if (err) {
            res.send(FAILURE);
            return;
        }
    });

    res.send(SUCCESS);
    return;
}

如果插入失敗, res.send(SUCCESS)已經被執行,然后執行con.query回調並調用res.send(FAILURE)

這只是一個例子。 您需要在整個請求中檢查您的代碼,以確保只發送一次響應。 如果您發送多次,您將看到ERR_HTTP_HEADERS_SENT (或類似錯誤 - 取決於您在響應對象上調用的 function)。 關鍵要點是您應該只發送一次響應,而且只發送一次。 如果下面沒有解決您的錯誤,您需要檢查您的應用程序的 rest 以確保您沒有再次發送響應,例如在您調用mysql_backend.castVote(req, res, uipv4, mysql);

要解決上述問題取決於所需的結果。

如果要向調用方返回錯誤已發生,則必須等到回調返回。 例如

if (!result.length) {
    // Cast vote here
    // ...
    // Add user's IP to voted list
    con.query(`INSERT INTO VotedUsers (ip) VALUES ('${ip}')`, function (err, result) {
        if (err) {
            res.send(FAILURE);
            return;
        }
        res.send(SUCCESS);
        return;
    });
}

2.有沒有更好的管理連接的方法

是——使用連接池 連接池允許您限制可以創建的連接數,例如,如果您有 100 個並行請求並且最大池大小為 10,則您將只能創建 10 個連接。

暫無
暫無

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

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