postgresql [ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置标头

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/54301624/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 02:45:02  来源:igfitidea点击:

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

javascriptnode.jspostgresql

提问by Carlos Torres

I'm working with PostgreSQL and NodeJS with its "PG Module". CRUD works but sometimes doesn't update automatically the views when i save or delete some item. this is my code and I think that the error is here but i cannot find it, i tried everything :'(

我正在使用带有“PG 模块”的 PostgreSQL 和 NodeJS。CRUD 有效,但有时在我保存或删除某些项目时不会自动更新视图。这是我的代码,我认为错误在这里,但我找不到它,我尝试了一切:'(

Error Message:

错误信息:

enter image description here

在此处输入图片说明

const controller = {};
const { Pool } = require('pg');

var connectionString = 'postgres://me:system@localhost/recipebookdb';
const pool = new Pool({
    connectionString: connectionString,
})

controller.list = (request, response) => {
    pool.query('SELECT * FROM recipes', (err, result) => {
        if (err) {
            return next(err);
        }
           return response.render('recipes', { data: result.rows });
    });
};

controller.save = (req, res) => {
    pool.query('INSERT INTO recipes(name, ingredients, directions) VALUES (, , )',
        [req.body.name, req.body.ingredients, req.body.directions]);
    return res.redirect('/');
};

controller.delete = (req, res) => {
    pool.query('DELETE FROM RECIPES WHERE ID = ', [req.params.id]);
    return res.redirect('/');
}

module.exports = controller;

PD: CRUD works but sometimes appears that error.

PD:CRUD 有效,但有时会出现该错误。

回答by Zunnurain Badar

This error occurs when you sent a response before and then you try to send response again. For this you have to check if there is any piece of code that is sending your response twice. Sometimes it happens due to asynchronous behavior of nodejs. Sometimes a process will be in event loop and we send response and when it finishes execution response will be sent again. So You can use callbacks or async await to wait for execution.

当您之前发送响应然后再次尝试发送响应时,会发生此错误。为此,您必须检查是否有任何代码两次发送您的响应。有时它是由于 nodejs 的异步行为而发生的。有时一个进程会在事件循环中,我们发送响应,当它完成执行时,响应将再次发送。因此您可以使用回调或异步等待来等待执行。

Callback

打回来

const controller = {};
const { Pool } = require('pg');

var connectionString = 'postgres://me:system@localhost/recipebookdb';
const pool = new Pool({
    connectionString: connectionString,
})

controller.list = (request, response) => {
    pool.query('SELECT * FROM recipes', (err, result) => {
        if (err) {
            return next(err);
        }
           return response.render('recipes', { data: result.rows });
    });
};

controller.save = (req, res) => {
    pool.query('INSERT INTO recipes(name, ingredients, directions) VALUES (, ,)',
        [req.body.name, req.body.ingredients, req.body.directions],function(err,resp) 
       {
         if(err){
          console.log(err)
      }else{
          return res.redirect('/');
      }
       });
};

controller.delete = (req, res) => {
    pool.query('DELETE FROM RECIPES WHERE ID = ',  [req.params.id],function(err,resp){
     if(err){
          console.log(err)
      }else{
          return res.redirect('/');
      }
 });
}

module.exports = controller;

Or You can also use async await to wait for execution and then send response.

或者您也可以使用 async await 等待执行然后发送响应。

Async/Await

异步/等待

const controller = {};
const { Pool } = require('pg');

var connectionString = 'postgres://me:system@localhost/recipebookdb';
    const pool = new Pool({
    connectionString: connectionString,
})

controller.list = async(request, response) => {
   try{
       const result = await pool.query('SELECT * FROM recipes');
       return response.render('recipes', { data: result.rows });
   }
    catch(err){
       return next(err);
   }
};

controller.save = async(req, res) => {
    try{
       await pool.query('INSERT INTO recipes(name, ingredients, directions) VALUES (, ,)',[req.body.name, req.body.ingredients, req.body.directions]);
       return res.redirect('/');
   }
    catch(err){
       return next(err);
   }
};

controller.delete = async(req, res) => {
    try{
        await pool.query('DELETE FROM RECIPES WHERE ID = ', [req.params.id]);
        return res.redirect('/');
    }catch(err){
       console.log(err);
    }
}

module.exports = controller;

回答by Vijay Kumar Attri

You need to embed your response in the callback to the query. Since the call is asynchronous, sending the response earlier will terminate the call stack never waiting for the webapi(Behaviour may vary).

您需要将您的响应嵌入到查询的回调中。由于调用是异步的,因此提前发送响应将终止调用堆栈,从不等待 webapi(行为可能会有所不同)。

controller.delete = (req, res) => {
    pool.query('DELETE FROM RECIPES WHERE ID = ', [req.params.id],(err, result) 
     => {
         // error handling can be done accordingly
        return res.redirect('/');
    })

}