Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/37.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 获得;错误[ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置头;当尝试重定向时_Javascript_Node.js_Mongodb - Fatal编程技术网

Javascript 获得;错误[ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置头;当尝试重定向时

Javascript 获得;错误[ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置头;当尝试重定向时,javascript,node.js,mongodb,Javascript,Node.js,Mongodb,我正在尝试创建一个包含数据库(mongodb)的简单服务器。我试图通过制作一个包含2个输入和一个发送按钮的简单表单来检查是否可以将数据插入其中,如下所示: index.html: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-sca

我正在尝试创建一个包含数据库(mongodb)的简单服务器。我试图通过制作一个包含2个输入和一个发送按钮的简单表单来检查是否可以将数据插入其中,如下所示:

index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <h1>Test</h1>
    <p>Test</p>

    <form action="/attack-data" method="POST">
        <input type="text" placeholder="name" name="name">
        <input type="text" placeholder="quote" name="quote">
        <button type="submit">Submit</button>
      </form>

</body>
</html>
我对这个问题已经很清楚了,我知道当服务器多次响应客户机时,就会发生这种情况,而我的服务器第二次响应是当我尝试重定向回post请求内部的主页时。但是我还没有找到我发送第一个回复的地方

后端:

let express = require('express');
let mongo = require('mongodb').MongoClient;
let bodyParser = require('body-parser');

let url = "mongodb://localhost:27017/database";
let port = 9999;
let app = express();

app.use(express.json());
app.use(bodyParser.urlencoded({extended: true}));

// Connecting to the database (The database is created if it doesn't exist)
mongo.connect(url, {useNewUrlParser:true, useUnifiedTopology:true}, function(error, client)
{
    if (error)
    {
        console.log("Error: Couldn't Create/Connect The Database");
        throw error;
    }
    console.log("Connection To The Database Has Been Established Successfully");
    const database = client.db('attack-patterns');
    const attackCollection = database.collection('temp');

    app.get('/', function(request, response)
    {
        response.sendFile(__dirname + '/public/index.html');
    })

    app.post('/attack-data', function(request, response)
    {
        console.log(request.body);
        attackCollection.insertOne(request.body)
        .then(function(result)
        {
            console.log(result);
            return response.redirect('/');
        })
        .catch(function(error)
        {
            console.log("Error: Couldn't Insert Data To Database: " + error);
            return response.status(404).json({error});
        })
        response.end();
    });

    client.close();
});


// Listening to the port saved in the variable "port"
app.listen(port, () => console.log("Server Is Listening To Port: " + port));
谢谢

response.end()是在您的
insertOne
承诺得到解决之前执行的,因此一旦处理程序(
then/catch
)被执行,响应就已经结束了,即消息头已经被发送。这就是为什么您会看到提到的错误

您可以简单地删除
response.end
语句,因为
response.redirect()和response.json()
已经处理了响应的发送

此外,您不应在mongo connect回调中声明路由处理程序,而应在其外部定义它们。

response.end()是在您的
insertOne
承诺得到解决之前执行的,因此一旦处理程序(
then/catch
)被执行,响应就已经结束了,即消息头已经被发送。这就是为什么您会看到提到的错误

您可以简单地删除
response.end
语句,因为
response.redirect()和response.json()
已经处理了响应的发送


此外,您不应在mongo connect回调中声明路由处理程序,而应在其外部定义它们。

在路由
/attack data
中,您在
attackCollection.insertOne
上开始承诺,并希望在
中发送响应。然后在
中捕获
.catch
但当启动承诺时,之后的代码将同时执行(在中启动承诺) 因此,在“.then”之前执行
响应.end()


您只需删除
response.end()
,您的代码就可以工作了

在路由
/attack data
中,您在
attackCollection.insertOne
上启动一个承诺,并希望在
中发送响应。然后在
中。catch
但当启动承诺时,之后的代码将同时执行(在中启动承诺) 因此,在“.then”之前执行
响应.end()


您只需删除
response.end()
,您的代码就可以工作了

这是因为您在数据库操作完成之前立即运行
response.end()
。这是因为您在数据库操作完成之前立即运行
response.end()
。哦,我现在明白了,非常感谢!我想补充一点:“在线程中启动承诺”是不正确的,承诺的回调会被推到微任务队列上,并在准备好后执行。没有第二个线程参与->哦,我现在明白了,非常感谢!我想补充一点:“在线程中启动承诺”是不正确的,承诺的回调会被推到微任务队列上,并在准备好后执行。没有涉及第二个线程->
let express = require('express');
let mongo = require('mongodb').MongoClient;
let bodyParser = require('body-parser');

let url = "mongodb://localhost:27017/database";
let port = 9999;
let app = express();

app.use(express.json());
app.use(bodyParser.urlencoded({extended: true}));

// Connecting to the database (The database is created if it doesn't exist)
mongo.connect(url, {useNewUrlParser:true, useUnifiedTopology:true}, function(error, client)
{
    if (error)
    {
        console.log("Error: Couldn't Create/Connect The Database");
        throw error;
    }
    console.log("Connection To The Database Has Been Established Successfully");
    const database = client.db('attack-patterns');
    const attackCollection = database.collection('temp');

    app.get('/', function(request, response)
    {
        response.sendFile(__dirname + '/public/index.html');
    })

    app.post('/attack-data', function(request, response)
    {
        console.log(request.body);
        attackCollection.insertOne(request.body)
        .then(function(result)
        {
            console.log(result);
            return response.redirect('/');
        })
        .catch(function(error)
        {
            console.log("Error: Couldn't Insert Data To Database: " + error);
            return response.status(404).json({error});
        })
        response.end();
    });

    client.close();
});


// Listening to the port saved in the variable "port"
app.listen(port, () => console.log("Server Is Listening To Port: " + port));