“错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置标头”

时间:2020-04-19 17:27:59

标签: javascript node.js express

这是我的index.js代码

var express = require("express");
var mysql = require('mysql');
var pug = require('pug');
var bodyparser = require('body-parser');
var app = express();

var conn = mysql.createConnection({
    host: "remotemysql.com",
    user: "",
    password: "",
    database: ""
});

conn.connect(function(err) {
    if (err) {
        console.log("Error connecting to MySQL:", err);
    } else {
        console.log("Connection established");
    }
});

let people = [];
let i = 0;

let subname = null;
let subemail = null;
let subsession = null;

app.set("views", "views");
app.set("view engine", "pug");
app.use(express.static("public"));
app.use(bodyparser());

app.get("/", function(req, res, next) {
    res.render("confirmed");
});

app.post("/register", function(req, res, next) {

    var attendees = {
        name: req.body.name,
        email: req.body.email,
        session: req.body.selectpicker
    };
    conn.query("INSERT INTO attendees SET ?", attendees, function(err, result, ) {
        if (err)
            res.send(err);
        else
            res.send("Thank You for registering!");
    });

    if (i = 0) {
        people.pop();
    }

    subname = req.body.name;
    subemail = req.body.email;
    subsession = req.body.session;

    let locals = {
        name: subname,
        email: subemail,
        session: subsession
    };
    people.push(subname + "," + subemail + "," + subsession);

    console.log(locals);
    console.log(subname);
    console.log(subemail);
    console.log(subsession);
    console.log("People: " + people);

    res.render("confirmed", locals);
});

//app.post("/register", function(req, res) {
//});

app.get("/list", function(req, res, next) {
    let peoplelist = {
        attendeelist: people
    }
    res.render("list", peoplelist);
});

app.listen(3000);

我不断收到错误消息 错误[ERR_HTTP_HEADERS_SENT]:将标头发送到客户端后无法设置标头 在ServerResponse.setHeader(_http_outgoing.js:526:11) 在ServerResponse.header(/home/runner/M18-CloudSecConf-with-DB/node_modules/express/lib/response.js:771:10)

我需要更改,移动或添加些什么才能使它消失。我在某种程度上理解它正在尝试将数据发送到服务器,然后无法设置标头,但是我不确定该怎么做。请帮忙,尝试学习这些东西。

1 个答案:

答案 0 :(得分:0)

您的/register路由处理程序在数据库回调内部有一个res.send(),并且在路由处理程序的末尾也有一个res.render()。这些尝试均尝试将请求发送到传入的http请求。但是,您只能为每个http请求发送一个http响应。

Express在第二次尝试发送响应的开始时就注意到了这个问题,当它尝试收集要发送给第二个响应的标头时,它注意到了这一问题,并且它看到标头已经被发送,因此消息你明白了。

因此,您需要删除res.send()res.render()或以某种方式将它们组合成一个响应。

相关的路由处理程序是这样的:

app.post("/register", function(req, res, next) {

    var attendees = {
        name: req.body.name,
        email: req.body.email,
        session: req.body.selectpicker
    };
    conn.query("INSERT INTO attendees SET ?", attendees, function(err, result, ) {
        // ATTEMPT #1 to send a response
        if (err)
            res.send(err);
        else
            res.send("Thank You for registering!");
    });

    if (i = 0) {
        people.pop();
    }

    subname = req.body.name;
    subemail = req.body.email;
    subsession = req.body.session;

    let locals = {
        name: subname,
        email: subemail,
        session: subsession
    };
    people.push(subname + "," + subemail + "," + subsession);

    console.log(locals);
    console.log(subname);
    console.log(subemail);
    console.log(subsession);
    console.log("People: " + people);

    // ATTEMPT #2 to send a response
    res.render("confirmed", locals);
});

仅供参考,您的if声明:

    if (i = 0) {

不正确。这会将0分配给i,然后对分配结果进行if,这不是您想要的。正确的if语句应为:

    if (i === 0) {

也不清楚您要使用通用名称为i的模块级变量(在所有用户和所有请求之间共享)做什么。这也可能是不正确的设计。

类似地,subnamesubemailsubsession之类的变量应在路由处理程序中本地声明,而不是在模块级别声明。

请记住,在路由处理程序外部声明的任何变量都将被所有用户和所有路由分片,这不是您通常想要的,除非持久状态由所有用户和服务器上的所有路由全局共享。