繁体   English   中英

在Express JS中发送标头后无法设置标头

[英]Can't set headers after they are sent in express js

我环顾了这个问题的先前答案,但是我不明白如果在多个路径中都有res.send() ,为什么会出现此错误。

我的代码是这样的(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)

我不确定发送响应后如何设置标题。

确保退货!

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

在中间件函数中,需要确保已发送响应后调用next() (例如,通过调用res.send()res.end()或类似方法)。

最简单的解决方案是在发送响应后立即从中间件返回:

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

您缺少一些return语句。 如果您不从函数status返回,并且多次在response对象上调用send ,并且最后还要调用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();
}

请确保在此代码后添加return语句

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

有可能

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

只要在该行之后返回任何内容,此后基本上就停止执行代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM