Node.js 错误[ERR_HTTP_HEADERS_SENT]:在发送到客户端后,第二次按下按钮时,无法设置头

Node.js 错误[ERR_HTTP_HEADERS_SENT]:在发送到客户端后,第二次按下按钮时,无法设置头,node.js,express,flutter,dart,Node.js,Express,Flutter,Dart,我目前正在学习颤振/飞镖,我正在尝试构建与服务器通信的应用程序,但我遇到了问题。有一个登录按钮,它向服务器发送请求,服务器检查是否有使用该用户名和密码的用户,并返回响应。第一次按下按钮时,一切正常,但如果第二次按下按钮,服务器上会弹出错误提示: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client at ServerResponse.setHeader (_http_outg

我目前正在学习颤振/飞镖,我正在尝试构建与服务器通信的应用程序,但我遇到了问题。有一个登录按钮,它向服务器发送请求,服务器检查是否有使用该用户名和密码的用户,并返回响应。第一次按下按钮时,一切正常,但如果第二次按下按钮,服务器上会弹出错误提示:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:526:11)
    at ServerResponse.header (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\node_modules\express\lib\response.js:771:10)
    at ServerResponse.send (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\node_modules\express\lib\response.js:170:12)
    at ServerResponse.json (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\node_modules\express\lib\response.js:267:15)
    at ServerResponse.send (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\node_modules\express\lib\response.js:158:21)
    at Function.<anonymous> (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\server.js:14:39)
    at Function.emit (events.js:326:22)
    at Query.<anonymous> (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\db.js:17:20)
    at Query.<anonymous> (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\node_modules\mysql\lib\Connection.js:526:10)
    at Query._callback (C:\Users\PC\Desktop\Flutter Node.js Login-Register App\server\node_modules\mysql\lib\Connection.js:488:16) {
  code: 'ERR_HTTP_HEADERS_SENT'
}
服务器

server.js

const express = require('express');
const app = express();
const database = require('./database.js');
const server = require('./server.json');

exports.app = app;

app.use(express.json());

app.post('/signin', async (req, res, next) => {
    const { username, password } = req.body;
    if (!validateUsernameAndPassword(username, password)) {
      // Remember to write a global error handler. Or don't use
      // Express' next(err) functionality but respond with a call-appropriate
      // response that has the correct HTTP error code, too.
      next(new Error("you better believe this should be an error"));
    }
    const value = await database.handleSignInRequest(username, password);
    res.send(value);
});

app.listen(server.port, () => console.log('Server running on port ' + server.port));
db.js


我将感谢任何帮助

当您依赖事件,但不将这些事件绑定到特定请求时,您会遇到麻烦:现在,请求映射到“nothing”,但随后代码会将触发响应的事件绑定到您曾经声明过的每个
app.on(“response”,…)
绑定。。。在这个过程中,还可以防止响应被垃圾收集,因为它们一直需要留下来处理事件。因此,您的代码也存在内存泄漏

不要对事件执行此操作,而是使用promissions/
async
函数,然后使用
wait
它们的返回值。这样,一个请求映射到一个响应,事情也会得到适当的清理

server.js

const express = require('express');
const app = express();
const database = require('./database.js');
const server = require('./server.json');

exports.app = app;

app.use(express.json());

app.post('/signin', async (req, res, next) => {
    const { username, password } = req.body;
    if (!validateUsernameAndPassword(username, password)) {
      // Remember to write a global error handler. Or don't use
      // Express' next(err) functionality but respond with a call-appropriate
      // response that has the correct HTTP error code, too.
      next(new Error("you better believe this should be an error"));
    }
    const value = await database.handleSignInRequest(username, password);
    res.send(value);
});

app.listen(server.port, () => console.log('Server running on port ' + server.port));
database.js:

const mysql = require('mysql');
const connectionUri = require('./db.json');
const db = mysql.createConnection(connectionUri);

// the db code shouldn't have to know anything about express or express apps

db.connect((err) => {
    if (err)
        throw err;
    console.log('MySQL connection successful!');
});

function handleSignInRequest(username, password) {
  return new Promise((resolve, reject) => {

    // Now, a super important note: NEVER QUERY A DATABASE DIRECTLY LIKE THIS:

    db.query(`SELECT Count(*) AS 'count' FROM Users WHERE (Username = '${username}' AND Password = '${password}')`, (err, result) => {
        if(err) return reject(err);
        resolve(result[0].count == 1 ? true : false);
    });

    // Look up how to query your database in a sanitized, prepared statement
    // fashion. https://xkcd.com/327/ is a word famous piece of satire for
    // good reason.
    //
    // Please read https://www.npmjs.com/package/mysql#preparing-queries and
    // put that into practice.
  });
});

module.exports = { handleSignInRequest };

答案作为答案,但作为对代码的直接注释:永远不要以这种方式编写数据库查询。很有趣,因为这是真的,所以请阅读并付诸实践。谢谢您的回答,先生,我非常感谢!
const express = require('express');
const app = express();
const database = require('./database.js');
const server = require('./server.json');

exports.app = app;

app.use(express.json());

app.post('/signin', async (req, res, next) => {
    const { username, password } = req.body;
    if (!validateUsernameAndPassword(username, password)) {
      // Remember to write a global error handler. Or don't use
      // Express' next(err) functionality but respond with a call-appropriate
      // response that has the correct HTTP error code, too.
      next(new Error("you better believe this should be an error"));
    }
    const value = await database.handleSignInRequest(username, password);
    res.send(value);
});

app.listen(server.port, () => console.log('Server running on port ' + server.port));
const mysql = require('mysql');
const connectionUri = require('./db.json');
const db = mysql.createConnection(connectionUri);

// the db code shouldn't have to know anything about express or express apps

db.connect((err) => {
    if (err)
        throw err;
    console.log('MySQL connection successful!');
});

function handleSignInRequest(username, password) {
  return new Promise((resolve, reject) => {

    // Now, a super important note: NEVER QUERY A DATABASE DIRECTLY LIKE THIS:

    db.query(`SELECT Count(*) AS 'count' FROM Users WHERE (Username = '${username}' AND Password = '${password}')`, (err, result) => {
        if(err) return reject(err);
        resolve(result[0].count == 1 ? true : false);
    });

    // Look up how to query your database in a sanitized, prepared statement
    // fashion. https://xkcd.com/327/ is a word famous piece of satire for
    // good reason.
    //
    // Please read https://www.npmjs.com/package/mysql#preparing-queries and
    // put that into practice.
  });
});

module.exports = { handleSignInRequest };