2016-08-31 10 views
0

この質問に対する以前の回答を見て回りましたが、複数のパスにres.send()がある場合、なぜこのエラーが発生するのか分かりません。エクスプレスjsで送信した後にヘッダーを設定できません

私のコードは次のようなもの(expressjs 4.13)である:私は私のフロントエンドからは何も送信しない場合は

var user ={ 
    username: "some", 
    password: "a" 
} 

router.post('/login', authenticate, function (req, res) { 
    //if it passes the middleware, send back the user 

    var token = jwt.sign({ 
     username: user.username 
    }, jwtSecret); 
    res.send({ 
     token: token, 
     user: user 
    }); 
}); 

function authenticate(req, res, next) { 
    var body = req.body; 
    var username = body.username, password = body.password; 

    //if nothing is sent 
    if(!username || !password){ 
     res.status(400).end('Must send a user and pass'); 
    } 

    //if incorrect credentials are sent 
    if(username !== user.username || password !== user.password){ 
     res.status(401).end("Incorrect credentials"); 
    } 

    //if it reaches here, it means credentials are correct 
    next(); 
} 

、私は400と、エラーメッセージを取得していますが、私のサーバーは、このことを示しています

POST /apis/auth/login 401 0.841 ms - - 
Error: Can't set headers after they are sent. 
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11) 
at ServerResponse.header  (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/response.js:718:10) 
at ServerResponse.json (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/response.js:246:10) 
at ServerResponse.send (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/response.js:151:21) 
at /home/vivek/dev/qwiksplit/jsback/app.js:81:9 
at Layer.handle_error (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/layer.js:71:5) 
at trim_prefix (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:310:13) 
at /home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:280:7 
at Function.process_params (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:330:12) 
at next (/home/vivek/dev/qwiksplit/jsback/node_modules/express/lib/router/index.js:271:10) 

応答が送信された後のヘッダーの設定方法がわかりません。

答えて

4

返品を確認してください!

return res.status(400).end('Must send a user and pass'); 
+0

これは意味があります。私はres.send()またはres.end()と言ったときに実行を中止し、デフォルトで返されると仮定しました。 –

+0

応答は終了しますが、コードはまだ実行されます。http://expressjs.com/en/api.html#res.end –

+0

これに加えて、Expressで実行されるすべてのものは、最後のコールバックでさえ「ミドルウェア」です。だから、あなたが 'authenticate'ミドルウェアで' next() 'を呼び出すと、router.postで提供したコールバック(ミドルウェアも)はまだ実行され、レスポンスはすでにあったとしても' res.send'も実行しようとします送信し、エラーが発生します。 – CreasolDev

1

一部のリターンステートメントがありません。関数statusから返されず、sendresponseオブジェクトで複数回呼び出され、最後にnextも呼び出されるため、今後のミドルウェアは応答に対しても動作します。あなたのミドルウェア機能で

function authenticate(req, res, next) { 
    var body = req.body; 
    var username = body.username, password = body.password; 

    //if nothing is sent 
    if(!username || !password){ 
     res.status(400).end('Must send a user and pass'); 
     return; 
    } 

    //if incorrect credentials are sent 
    if(username !== user.username || password !== user.password){ 
     res.status(401).end("Incorrect credentials"); 
     return; 
    } 

    //if it reaches here, it means credentials are correct 
    next(); 
} 
2

は、あなたがnext()あなたは既に(res.send()res.end()または類似を呼び出すことによって、例えば)応答を送信した後に呼び出されていないであることを確認する必要があります。

res.status(400).end('Must send a user and pass'); 

それができる

function authenticate(req, res, next) { 
    var body = req.body; 
    var username = body.username, password = body.password; 

    if(!username || !password){ 
     res.status(400).end('Must send a user and pass'); 
     return; // <----- 
    } 

    if(username !== user.username || password !== user.password){ 
     res.status(401).end("Incorrect credentials"); 
     return; // <----- 
    } 

    next(); 
} 
0

このコードの後に​​return文を追加することを確認してください:

最も簡単な解決策はちょうどあなたが応答を送信した直後に、あなたのミドルウェアから返すことです

return; or return res.status(400).end('Must send a user and pass'); 

その行の後に何かを返すだけで、基本的にあなたの共同それ以降。

関連する問題