【问题标题】:[ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client[ERR_HTTP_HEADERS_SENT]:发送到客户端后无法设置标头
【发布时间】:2019-06-15 12:44:50
【问题描述】:

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

错误信息:

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 有效,但有时会出现该错误。

【问题讨论】:

  • 请将异常发布为文本,而不是图像。这使您的问题更易于搜索和阅读。

标签: javascript node.js postgresql


【解决方案1】:

您需要将您的响应嵌入到查询的回调中。由于调用是异步的,因此提前发送响应将终止调用堆栈,从不等待 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】:

    当您之前发送过响应然后您尝试再次发送响应时会发生此错误。为此,您必须检查是否有任何代码将您的响应发送两次。有时它是由于 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;
    

    或者你也可以使用 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 ($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;
    

    【讨论】:

      【解决方案3】:

      检查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);
            }
      

      【讨论】:

      • 作为补充:我正在关注一个设置 MEAN 堆栈的教程。我在数组上方留下了res.send('text');,然后我使用res.json(array) 再次在 res 上发送了一些东西。一旦我删除了无用的res.send() 就很好了。
      猜你喜欢
      • 2019-02-06
      • 2020-05-20
      • 2019-12-11
      • 1970-01-01
      • 1970-01-01
      • 2019-06-02
      • 2020-06-21
      • 2021-07-21
      • 1970-01-01
      相关资源
      最近更新 更多