Sails错误:抛出新错误('不能在发送后设置标题.')

shu*_*l92 3 mongoose node.js sails.js waterline

嗨,我是Sails的新手,我正在尝试通过禁用水线功能使用Sails连接到Mongoose.在执行POST操作的Sails中执行我的代码时,遇到以下问题

/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:108
 if (this.ended && !this.hasRejectListeners()) throw reason;
                                                  ^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:335:11)
at ServerResponse.res.setHeader (/usr/local/lib/node_modules/sails/node_modules/express/node_modules/connect/lib/patch.js:133:22)
at ServerResponse.res.set.res.header (/usr/local/lib/node_modules/sails/node_modules/express/lib/response.js:577:10)
at ServerResponse.res.send (/usr/local/lib/node_modules/sails/node_modules/express/lib/response.js:142:12)
at ServerResponse.res.json (/usr/local/lib/node_modules/sails/node_modules/express/lib/response.js:223:15)
at EventEmitter.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/api/controllers/Status-packetController.js:74:17)
at EventEmitter.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:175:45)
at EventEmitter.emit (events.js:110:17)
at Promise.safeEmit (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:81:21)
at Promise.fulfill (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:94:24)
at Promise.resolve (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/lib/promise.js:113:23)
at model.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/lib/document.js:1578:39)
at next_ (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/hooks-fixed/hooks.js:89:34)
at EventEmitter.fnWrapper (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/hooks-fixed/hooks.js:171:15)
at EventEmitter.<anonymous> (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:175:45)
at EventEmitter.emit (events.js:110:17)
at Promise.safeEmit (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:81:21)
at Promise.fulfill (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:94:24)
at p1.then.then.self.isNew (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/lib/model.js:254:27)
at newTickHandler (/Users/febinp/Documents/Tecsol/Taqua/Taqua-loginpacket/node_modules/mongoose/node_modules/mpromise/lib/promise.js:229:18)
at process._tickDomainCallback (node.js:381:11)
Run Code Online (Sandbox Code Playgroud)

我的守则如下

CreateStatus: function (req, res) {
  var params = req.body;
  if(params.SerialNo == null) {
    var response = {};
    response.success = "FALSE";
    response.error = "Serial.NO.is.Null";
    res.json(response);
    return(res);
  }
  // For Authenfication purpose Only
  var mongoose = require('mongoose');
  var login = mongoose.model('Login');
  var SerialNo1 = req.body.SerialNo;

  login.find({ "SerialNo": SerialNo1 }, function (err,data) {
    if(err) {
      res.json({
        success: false,
        error: err
      });
      return;      
    } else {
      if(data.length <= 0) {
        res.json({
          success: false,
          error: "User Doesn't Exists"
        });
        return;          
      }  
    }
  });
  // End of Authentification  

  var msg_parts = params.msg_parts;


  // CONVERSION ALGORITHM FROM INTEGER TO BOOLEAN
  if(msg_parts.chargingStatus <= 0)
    msg_parts.chargingStatus = false;
  else
    msg_parts.chargingStatus = true;

  if(msg_parts.alarmInfo <= 0)
    msg_parts.alarmInfo = false;
  else
    msg_parts.alarmInfo = true;

  if(msg_parts.gpsStatus <= 0)
    msg_parts.gpsStatus = false;
  else
    msg_parts.gpsStatus = true;

  msg_parts.SerialNo = params.SerialNo; // Adding the Serial no into the message parts
  // CONVERSION ALGORITHM FROM INTEGER TO BOOLEAN finished

  var statuspacket = db.StatusPacket(msg_parts);
  // For saving into the Database
  statuspacket.save(function (err,data) {
    if(err) {
      res.json({
        success: false,
        exception: err
      });
      return;
    }
    res.json({
      success: true,
      data:data
    });
    return;  
  });
}
Run Code Online (Sandbox Code Playgroud)

基本上我的代码只是将数据输入数据库,在此之前执行用户的身份验证部分.一旦我得到DHCP并点击Post I Encounter上面提到的问题.我的数据被存储到数据库中,但风帆正在下降.我的架构如下

// Serial No of the device.We require an Index on this column
SerialNo: {
  type: String,
  required: true
},
batteryLevel: {
  type: Number,
  min: 0, // battery level will take values from 0 to 6(0,1,2,3,4,5,6)
  max: 6
},
signalLevel: {
  type: Number,
  min: 0, // Signal Level will take values from 0 to 4 (0,1,2,3,4)
  max: 4,
},
chargingStatus: {
  type: Boolean,   
  default: false
},
alarmInfo: {
  type: Boolean,
  default: false
},
gpsStatus: {
  type: Boolean
},
createdAt: {
  type: Date,
  default: Date.now
},
PurgeDataNumber: {
  type:Number
}
Run Code Online (Sandbox Code Playgroud)

我的路线

'/Status-packet/CreateStatus': 'Status-packetController.CreateStatus',
'/Status-packet/FindStatus': 'Status-packetController.FindStatus'
Run Code Online (Sandbox Code Playgroud)

有人可以帮助我解决这个问题,为什么我的风帆应用程序正在进行后期操作?

Yan*_*and 8

Error: Can't set headers after they are sent.
Run Code Online (Sandbox Code Playgroud)

正如@nfleury所说,当您尝试res.*多次向客户端发送响应()时,会抛出此错误.

让我们找到问题所在.

乍一看,没有问题.你return每次使用时都会打电话res.json.

那个问题必须更加复杂.也许是异步函数的问题?

CreateStatus: function (req, res) {
  // No problem at the beginning
  // ... 

  // Here you call an asynchronous function
  // Let's name it "function 1"
  login.find({ "SerialNo": SerialNo1 }, function (err, data) {
    if(...) {
      res.json(...);
      return;      
    }
  });
  // You've called function 1 but the code continues to be executed

  // ...

  // Another async function is called
  // Let's name it "function 2"
  statuspacket.save(function (err, data) {
    res.json(...);
    return;  
  });
}
Run Code Online (Sandbox Code Playgroud)

正如我们所见,函数1和2都被调用.我假设调用回调时出现问题.

函数2回调总是向客户端发送响应.如果验证了一系列条件,则函数1回调也会发送响应.得到它了!

现在.我们如何解决这个问题?

我想你想要做的是等到第一个回调被调用后再继续.你可以这样做:

login.find({ "SerialNo": SerialNo1 }, function (err, data) {
  // Function 1 has complete
  if(...) {
    res.json(...);
    return;      
  }

  // ...

  statuspacket.save(function (err, data) {
    res.json(...);
    return;  
  });
});
Run Code Online (Sandbox Code Playgroud)