Node Error : can't set headers after they are sent. How to solve?

Node Error : can't set headers after they are sent. How to solve?

用户单击登录按钮后,服务器通过显示错误自行关闭 "Can't set headers after they are send."有帮助吗?

Server.js 文件

app.put('/users/signin',function(req,res,next){
    db.collection('users',function(err,usersCollection){
        usersCollection.findOne({username:req.body.username},function(err,user){
            bcrypt.compare(req.body.password,user.password,function(err,result){
                if(result){
                    var token = jwt.encode(user,JWT_SECRET);
                    return res.json({token:token});
                }else{
                    res.status(400).send();
                }
            })
        });   
    });
    res.send();
});

我正在调用服务器的控制器..

$scope.signin = function(){
                  $http.put('/users/signin',{username:$scope.username,password:$scope.password})
         .then(function(res){
               $cookies.put('token',res.data.token);
               $scope.currentUser = $scope.username;
               alert("Successfully signed in");
           },function(err){
               alert("bad login credentials");
           });
    };

usersCollection.findOne 是异步的,它的回调在 res.send(); 被调用之后被调用。

res.send(); 移动到 bcrypt.compare 回调中。

app.put('/users/signin', function(req, res, next) {
    db.collection('users', function(err, usersCollection) {
        usersCollection.findOne({ username: req.body.username }, function(err, user) {
            bcrypt.compare(req.body.password, user.password, function(err, result) {
                if (result) {
                    var token = jwt.encode(user, JWT_SECRET);
                    res.json({ token: token });
                } else {
                    res.status(400);
                }

                // like here
                res.send();
            });
        });
    });
});

什么是回调?

来自wikipedia一个回调是一段可执行代码,作为参数传递给其他代码。根据定义,回调没有任何异步,但它是用于异步编程的一个非常有用的概念。

在 JavaScript 中,函数可以将函数引用作为参数作为回调。

function someFunction(callback) {
    console.log("before async callback");
    setTimeout(callback, 1); // calls the callback asynchronously
    console.log("after async callback");
}

可以这样调用,使用现有函数

function myExistingFunction() {
    console.log("inside a callback");
}
someFunction(myExistingFunction); 

或者像这样,使用函数表达式

someFunction(function(){ 
    console.log("inside a callback");
});

someFunction 的两次调用都会将以下内容打印到控制台 按此顺序 :

before async callback
after async callback
inside a callback

为什么要按这个顺序?

由于 someFunction 将回调传递给异步函数 setTimeout,因此不会立即调用回调,而是仅在调用堆栈完成后调用。所以 someFunction 完全完成,然后稍后调用我们的回调。

看看