简体   繁体   English

Node Express MySQL和错误:发送标头后无法设置标头

[英]Node Express MySQL and the Error: Can't set headers after they are sent

I am working with Node.js, Express.js, and a MySQL database. 我正在使用Node.js,Express.js和MySQL数据库。 Within the database I have posts that I would like to display using Pug.js view engine. 在数据库中,我想使用Pug.js视图引擎显示帖子。 I got it to work by connecting to the database and rendering the home route correctly but I am apparently making a second callback because I get the Error: 我可以通过连接到数据库并正确渲染本地路由来使其正常工作,但是我显然在进行第二次回调,因为出现错误:

Can't set headers after they are sent. 发送标头后无法设置。

I am unsure of how to fix this without breaking it further because it actually renders as expected now. 我不确定如何解决此问题而不作进一步介绍,因为它现在实际上已按预期呈现。 Here is what I am working with: 这是我正在使用的:

app.js: app.js:

// Home Route
app.get('/', function(req, res){

  //get posts from database to show on news section.
  var postList =  [];

  db.query('SELECT * from articles', function(err, rows) {

    if(err) throw err;
    for (var i = 0; i < rows.length; i++) {
      //missing the img fields
      var post = {
        'id':rows[i].id,
        'title':rows[i].title,
      }
      //Add the newly created post object to the postList array
      postList.push(post);

      //THE ERROR IS PROBABLY BECAUSE OF THIS \/

      res.render('index', {
        title:'mySite',
        page: 'News',
        postList: postList});
    }
  });
});

here is the index.pug: 这是index.pug:

extends layout

block content
  table
    for post in postList
      tr
        td
          h3 #{post.title}
        td
          p #{post.id}

Once again it renders fine but the terminal is throwing the error at me and i would prefer to fix it if possible. 它再次呈现良好,但是终端向我抛出错误,如果可能的话,我希望修复它。 I have tried to pull the res.render for the index out of the query like this: 我试图像这样从查询中提取索引的res.render:

// Home Route
app.get('/', function(req, res){

  //get posts from database to show on news section.
  var postList =  [];

  db.query('SELECT * from articles', function(err, rows) {

    if(err) throw err;
    for (var i = 0; i < rows.length; i++) {
      //missing the img fields
      var post = {
        'id':rows[i].id,
        'title':rows[i].title,
      }
      //Add the newly created post object to the postList array
      postList.push(post);

    }
  });
      //THIS FIXES THE ERROR \/

      res.render('index', {
        title:'mySite',
        page: 'News',
        postList: postList});
      //THIS NO LONGER RENDERS THE postList ARRAY
});

Any help with this would be appreciated. 任何帮助,将不胜感激。 Thanks. 谢谢。

You almost made it right, man! 你几乎说对了,伙计! but the render should be inside db.query such as 但是render应该在db.query内部,例如

//get posts from database to show on news section.
  var postList = [];

  db.query('SELECT * from articles', function (err, rows) {

    if (err) throw err;
    for (var i = 0; i < rows.length; i++) {
      //missing the img fields
      var post = {
        'id': rows[i].id,
        'title': rows[i].title,
      }
      //Add the newly created post object to the postList array
      postList.push(post);

    } // end for loop

    res.render('index', {
      title: 'mySite',
      page: 'News',
      postList: postList
    });
  });

The explanation is db.query is callback function, if you put res.render outside it, javascript engine will execute it first so you will get nothing in your postList . 解释是db.query是回调函数,如果将res.render放在res.render外部,则javascript引擎将首先执行它,因此postList什么也不会得到。 So, you must wait until db.query finish and populate your postList then render it. 因此,您必须等待db.query完成并填充postList然后进行渲染。

Why you got Can't set headers after they are sent because you execute res.render multiple times (you put it inside the loop). 为何原因发送标头后无法设置标头,因为您多次执行res.render (将其放入循环中)。 It must be executed just once. 它只能执行一次。

Hope it helps. 希望能帮助到你。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM