发送后无法设置 headers。使用 Mongo 创建 sub-document 时出错

Can't set headers after they are sent. Error when Creating a sub-document with Mongo

我正在尝试通过邮递员使用我的快递 API 创建一个 sub-document,请求如下:

POST /api/course/58c6f76e06e6edda1b000007/subject/58c6f85280a5d6591c000007/question

我也正在发送 x-www-forum-urlencoded 带有名称问题和答案的数据。

这是终端中输出的错误:

Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.header (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/response.js:719:10)
at ServerResponse.send (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/response.js:164:12)
at ServerResponse.json (/home/tyler/Dropbox/Projects/Curricula/node_modules/express/lib/response.js:250:15)
at sendJSONResponse (/home/tyler/Dropbox/Projects/Curricula/API/controllers/question.js:8:8)
at Promise.<anonymous> (/home/tyler/Dropbox/Projects/Curricula/API/controllers/question.js:36:10)
at Promise.<anonymous> (/home/tyler/Dropbox/Projects/Curricula/node_modules/mpromise/lib/promise.js:171:8)
at emitOne (events.js:77:13)
at Promise.emit (events.js:169:7)
at Promise.emit (/home/tyler/Dropbox/Projects/Curricula/node_modules/mpromise/lib/promise.js:88:38)

这是我的控制器文件和相关数据模型:

var mongoose = require('mongoose');
var Course = mongoose.model('Course');
var Subject = mongoose.model('Subject');
var Question = mongoose.model('Question');

var sendJSONResponse = function(res, status, content){
   res.status(status);
   res.json({content});
};

var addQuestion = function(req, res, subject){
  if(!subject){
    sendJSONResponse(res, 404, {"message":"subjectid not found"});
    return;
  }
  else{
    subject.questions.push({question: req.body.question,
                            answer: req.body.answer,
                            falseAnswer: req.body.falseanswer});
    subject.save(function(err, course){
      var thisQuestion
      if(err){
        sendJSONResponse(res, 400, err);
      } else{
        thisQuestion = subject.questions[subject.questions.length - 1];
        sendJSONResponse(res, 201, thisQuestion);
      }
    });
  }
}

var seekSubject = function(req, res, course){
  if(req.params && req.params.subjectid){
    Subject.findById(req.params.subjectid).exec(function(err, subject){
      if(!subject){
         sendJSONResponse(res, 404, {"message":"subjectid not found"});
      }
      else if(err){
         sendJSONResponse(res, 404, err);
         return;
      }
      sendJSONResponse(res, 200, subject);
      return subject
      });
  } else{
     sendJSONResponse(res, 404, {
        "message":"no subjectid in request"
     });
  }
};

module.exports.makeQuestion = function(req, res){
    var courseid = req.params.courseid;
    if(courseid) Course.findById(courseid).select('subjects').exec(
      function(err, course){
        if(err){
          sendJSONResponse(res, 400, err);
          return;
        }
        else var subject =  seekSubject(req, res, course);
        addQuestion(req, res, subject);
    });
}

课程模型

var mongoose = require('mongoose')
var subject = require('./subject.js');

var courseSchema = new mongoose.Schema({
   name : {type: String,
            unique: true,
            required: true},
   subjects : [subject.schema]
});

主题模型

module.exports = mongoose.model('Course', courseSchema);

var mongoose = require('mongoose')
var question = require('./question.js');

var subjectSchema = new mongoose.Schema({
   name : String,
   questions : [question.schema]
});
module.exports = mongoose.model('Subject', subjectSchema);

问题模型

var mongoose = require('mongoose')

var questionSchema = new mongoose.Schema({
   question: {type: String, required: true},
   answer: {type: String, required: true},
   falseAnswer: [String]
});

module.exports = mongoose.model('Question', questionSchema);

我在创建条目时做错了什么?

可能在这个区域

else var subject =  seekSubject(req, res, course);
        addQuestion(req, res, subject);

这 2 个函数,seekSubjectaddQuestion 似乎都在调用 sendJSONResponse 并且它们似乎都在发送响应

res.status(status); res.json({content});

因此,如果在该区域调用了两个函数,您可能会发送 2 个响应,这就是您收到该错误的原因。

你通过分离关注点做得很好,但你也必须将错误的东西分开。当您调用 2 函数时,您告诉服务器响应两次。我认为你同时调用了这两个函数。我没有 运行 你的代码。

你得到这个是因为你发送了 2 个响应,而你应该只发送 1 个。尝试执行以下操作:

res.status(500).json({ error: 'message' });

或者您可能想尝试在 sendJSONResponse(res, status, content); 之前使用 return,例如:

return sendJSONResponse(res, 404, {"message":"subjectid not found"});

希望对您有所帮助。