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

时间:2019-01-22 05:13:58

标签: javascript node.js postgresql

我正在使用PostgreSQL和NodeJS及其“ PG模块”。 CRUD可以工作,但是当我保存或删除某些项目时,有时不会自动更新视图。这是我的代码,我认为错误在这里,但我找不到它,我尝试了所有的方法:'(

错误消息:

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 ($1, $2, $3)',
        [req.body.name, req.body.ingredients, req.body.directions]);
    return res.redirect('/');
};

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

module.exports = controller;

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

3 个答案:

答案 0 :(得分:3)

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

回调

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 ($1, $2,$3)',
        [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 = $1',  [req.params.id],function(err,resp){
     if(err){
          console.log(err)
      }else{
          return res.redirect('/');
      }
 });
}

module.exports = controller;

或者您也可以使用异步等待来等待执行,然后发送响应。

异步/等待

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 ($1, $2,$3)',[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 = $1', [req.params.id]);
        return res.redirect('/');
    }catch(err){
       console.log(err);
    }
}

module.exports = controller;

答案 1 :(得分:0)

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

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

}

答案 2 :(得分:0)

检查res.send()不应调用两次。

在控制器中

const getAll = function(req, res){
   res.send(service.getAll(req,res));
  }

服务中

const Type = require("../models/type.model.js");
exports.getAll = (req, res) => {
  Type.getAll((err, data) => {  
    res.send(data);
  });
};

res.send(data); 之上,两次调用会产生问题。更好地使用

const getAll = function(req, res){
        service.getAll(req,res);
      }