Javascript Can';t在express js中发送邮件后设置邮件头

Javascript Can';t在express js中发送邮件后设置邮件头,javascript,node.js,express,Javascript,Node.js,Express,我环顾了一下以前对这个问题的回答,但我不明白如果在多个路径中有res.send(),为什么会出现这个错误 我的代码是这样的(expressjs4.13): 当我没有从前端发送任何内容时,我会收到400和错误消息,但我的服务器显示: POST /apis/auth/login 401 0.841 ms - - Error: Can't set headers after they are sent. at ServerResponse.OutgoingMessage.setHeader (_htt

我环顾了一下以前对这个问题的回答,但我不明白如果在多个路径中有
res.send()
,为什么会出现这个错误

我的代码是这样的(expressjs4.13):

当我没有从前端发送任何内容时,我会收到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');
一定要回来

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

您缺少一些返回语句。如果您没有从函数
status
返回,并且
send
response
对象上被多次调用,最后甚至调用了
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();
}

您缺少一些返回语句。如果您没有从函数
status
返回,并且
send
response
对象上被多次调用,最后甚至调用了
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();
}

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

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

功能验证(req、res、next){
var body=请求body;
var username=body.username,password=body.password;
如果(!用户名| |!密码){
res.status(400).end('必须发送用户并通过');

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

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

功能验证(req、res、next){
var body=请求body;
var username=body.username,password=body.password;
如果(!用户名| |!密码){
res.status(400).end('必须发送用户并通过');

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

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

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

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

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

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

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

只要在那一行之后返回任何内容,基本上在那之后停止代码的执行。

这是有道理的。当我说res.send()或res.end()时,我假设,执行将在此停止,默认情况下将返回。响应将结束,但之后的代码仍将执行,以添加到响应中,在Express中完成的所有操作都是“中间件”,甚至是最后一次回调。因此,当您在
身份验证
中间件中调用
next()
时,回调(也是中间件)您在router.post中提供的仍然会运行并尝试运行
res.send
,即使响应已经发送,这会导致错误。这是有道理的。当我说res.send()或res.end()时,我假设,执行将在此停止,默认情况下将返回。响应将结束,但之后的代码仍将执行,以添加到响应中,在Express中完成的所有操作都是“中间件”,甚至是最后一次回调。因此,当您在
身份验证
中间件中调用
next()
时,回调(也是中间件)您在router.post中提供的仍然会运行并尝试运行
res.send
,即使响应已经发送,这会导致错误。