Sails Error:throw new Error('Can\'t set headers after they are sent.')

Sails Error:throw new Error('Can\'t set headers after they are sent.')

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

/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)

我的代码如下

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

基本上,我的代码只是将数据输入到数据库中,然后再执行用户身份验证部分。一旦我进入 DHCP 并点击 Post 我就遇到了上面提到的问题。我的数据正在存储到数据库中,但是风帆正在下降。我的架构如下

// 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
}

我的路线

'/Status-packet/CreateStatus': 'Status-packetController.CreateStatus',
'/Status-packet/FindStatus': 'Status-packetController.FindStatus'

有人可以帮我解决这个问题,为什么我的 sails 应用程序在 post 操作中出现故障?

Error: Can't set headers after they are sent.

通常当您遇到此错误时,这意味着您发送了两次响应...

可能是因为:

statuspacket.save(function (err,data) {
  if(err) {
    res.json({
      success: false,
      exception: err
    });
    return;
  }
  res.json({
    success: true,
    data: data
  });
  return;  
});

如果您遇到错误,它将再次发送 json 响应...看起来您在这里缺少 'else' ...

Error: Can't set headers after they are sent.

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

让我们找出问题。

乍一看,没有问题。每次使用 res.json.

时调用 return

那问题肯定更复杂。可能是异步函数的问题?

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

如我们所见,函数 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;  
  });
});