57

我有一个相当简单的 Express.js 应用程序,它带有一个登录组件,如果登录失败,我想提前退出。我看到有迹象表明该应用程序没有这样做,并且我还没有找到明确的答案来表明调用是否会res.send()停止任何进一步的处理。这是我现在的代码:

client.login( username, password, function( auth, client ) {
  if( !auth ) {
    res.send( 401 );
  }

  // DO OTHER STUFF IF AUTH IS SUCCESSFUL
}

如果我正确阅读了源代码,它应该结束请求(中止进一步处理),但我是节点新手,所以我还没有准备好相信我认为我正在阅读的内容。归根结底,我想我主要是从更可靠的来源中寻找明确的答案,而不是我自己对不熟悉的源代码的解释。如果send()不中止处理,那么正确的方法是什么?

4

7 回答 7

69

当然 express 不能神奇地让你的 javascript 函数停止从其他地方执行。

我不喜欢 next([error]) 解决方案,因为我认为错误应该只用于您通常不期望的情况(例如无法访问的数据库或其他情况)。在这种情况下,一个简单的错误密码就会导致错误。对普通控制流不使用异常/错误是一种常见的约定。

因此,我建议在 res.send 调用之后放置一个 return 语句,以使您的函数停止进一步执行。

client.login( username, password, function( auth, client ) {
  if( !auth ) {
    res.send( 401 );
    return;
  }

  // DO OTHER STUFF REALLY ONLY IF AUTH IS SUCCESSFUL
}
于 2013-10-11T07:15:57.917 回答
43

如果你使用 express 作为你的框架,你应该调用 next() 来代替。

express 中的每个处理程序都接收 3 个参数(基本 http 为 unlinke 2),它们是req,resnext

next是一个函数,当不带参数调用时将触发中间件链中的下一个处理程序。

如果next使用参数调用,则无论该参数的类型如何,该参数都将被解释为错误。

它的签名是next([error]). 当 next 被错误调用时,它不会调用中间件链中的下一个处理程序,而是调用错误处理程序。您应该在该错误处理程序中处理 401 响应代码。有关Express 中的错误处理的更多信息,请参阅此内容

编辑:正如@Baptiste Costa评论的那样,简单地调用next()不会停止当前的执行,但它会调用下一个中间件。最好使用它return next()来防止 Node 进一步抛出错误(例如can't set headers after they are sent- 错误)。这包括上述常见的错误抛出建议:

return next(new Error([error]));
于 2013-02-05T15:36:17.403 回答
2

对于您的具体情况,您只需添加“else”语句:

client.login( username, password, function( auth, client ) {
    if( !auth ) {
        res.send( 401 );
    }else {
       // DO OTHER STUFF IF AUTH IS SUCCESSFUL
    }
}

或者,一般来说,您可以使用“return”:

return res.send( 401 );
于 2020-09-09T18:13:08.313 回答
0

只需执行类似的操作即可停止进一步执行。

function (request, response, next) {
    var path = request.body.path;

    if(path === undefined){
        response.status(HttpStatus.BAD_REQUEST);
        response.send('path is required!');
    }

    next(response)
};
于 2019-06-21T17:54:26.937 回答
0

在这些情况下,我倾向于使用 try...catch bloc。

client.login( username, password, function( auth, client ) { 

 try{
   if(error1){
    throw {status : 401 , message : 'error1'}
   }
   if(error2){
    throw {status : 500 , message : 'error2'}
   }
 }catch(error){
   res.status(error.status).json(error.message);
 }

}
于 2021-05-08T23:11:20.737 回答
-3

您只需要返回即可结束流程:

return  res.send( 401 );

这将发回 401 响应,并且不会在流程中继续前进。

于 2018-07-20T17:07:51.423 回答
-7

为什么没有人建议使用“else”块?

if(!auth){
    // Auth fail code
    res.send 'Fail'
} else {
    // Auth pass code
    res.send 'Pass'
}

'next' 在为“app.use(function(req, res, next));”创建自己的中间件时使用。如果你设置了类似“app.get(route, function(req, res));”的路由 那么函数中的代码就是您可以在其中使用您指定的代码而无需使用“下一步”的地方。

于 2013-12-03T14:07:20.087 回答