如何在node / express中发送自定义http状态消息?

我的node.js应用程序像express / examples / mvc应用程序一样build模。

在一个控制器动作中,我想用自定义的http消息吐出一个HTTP 400的状态。 默认情况下,http状态消息是“错误的请求”:

HTTP/1.1 400 Bad Request 

但我想发

 HTTP/1.1 400 Current password does not match 

我尝试了各种方法,但没有一个将http状态消息设置为我的自定义消息。

我目前的解决scheme控制器function如下所示:

 exports.check = function( req, res) { if( req.param( 'val')!=='testme') { res.writeHead( 400, 'Current password does not match', {'content-type' : 'text/plain'}); res.end( 'Current value does not match'); return; } // ... } 

一切正常,但…似乎不是正确的做法。

有没有更好的方法来设置http状态消息使用快递?

你可以检查这个res.send(400, 'Current password does not match')看明确的3.x文档的细节

更新Expressjs 4.x

使用这种方式(看快递4.x文档 ):

 res.status(400).send('Current password does not match'); // or res.status(400); res.send('Current password does not match'); 

现有的答案都没有完成OP最初要求的内容,即覆盖Express发送的默认Reason-Phrase (状态码后立即出现的文本)。

你想要的是res.statusMessage 。 这不是Express的一部分,它是Node.js 0.11+中底层http.Response对象的一个​​属性。

您可以像这样使用它(在Express 4.x中testing):

 function(req, res) { res.statusMessage = "Current password does not match"; res.status(400).end(); } 

然后使用curl来validation它的工作原理:

 $ curl -i -s http://localhost:3100/ HTTP/1.1 400 Current password does not match X-Powered-By: Express Date: Fri, 08 Apr 2016 19:04:35 GMT Connection: keep-alive Content-Length: 0 

在express中处理自定义错误的一种优雅的方式是:

 function errorHandler(err, req, res, next) { var code = err.code; var message = err.message; res.writeHead(code, message, {'content-type' : 'text/plain'}); res.end(message); } 

(你也可以使用快速'内置express.errorHandler这个)

然后在你的中间件中,在你的路由之前:

 app.use(errorHandler); 

然后,您要创build错误“当前密码不匹配”的位置:

 function checkPassword(req, res, next) { // check password, fails: var err = new Error('Current password does not match'); err.code = 400; // forward control on to the next registered error handler: return next(err); } 

在服务器端(Express中间件):

 if(err) return res.status(500).end('User already exists.'); 

在客户端处理

angular度: –

 $http()..... .error(function(data, status) { console.error('Repos error', status, data);//"Repos error" 500 "User already exists." }); 

jQuery的: –

 $.ajax({ type: "post", url: url, success: function (data, text) { }, error: function (request, status, error) { alert(request.responseText); } }); 

我的用例是发送一个自定义的JSON错误信息,因为我正在使用express来驱动我的REST API。 我认为这是一个相当常见的情况,所以我会在回答中关注这个问题。

简洁版本:

Expresserror handling

定义像其他中间件一样的error handling中间件,除了四个参数而不是三个,特别是签名(err,req,res,next)。 …最后定义error handling中间件,在其他app.use()和路由调用之后

 app.use(function(err, req, res, next) { if (err instanceof JSONError) { res.status(err.status).json({ status: err.status, message: err.message }); } else { next(err); } }); 

通过执行代码中的任何一点引发错误:

 var JSONError = require('./JSONError'); var err = new JSONError(404, 'Uh oh! Can't find something'); next(err); 

长版本

抛出错误的规范方式是:

 var err = new Error("Uh oh! Can't find something"); err.status = 404; next(err) 

缺省情况下,Express通过将其整体打包为代码为404的HTTP响应以及由附加了堆栈跟踪的消息string组成的主体来处理此问题。

例如,当我将Express用作REST服务器时,这不起作用。 我想要将错误作为JSON发回,而不是HTML。 我也绝对不希望我的堆栈跟踪移动到我的客户端。

我可以使用req.json()发送JSON作为响应,例如。 像req.json({ status: 404, message: 'Uh oh! Can't find something'}) 。 或者,我可以使用req.status()来设置状态码。 结合两者:

 req.status(404).json({ status: 404, message: 'Uh oh! Can't find something'}); 

这就像一个魅力。 也就是说,我发现每次出现错误时都input相当不方便,代码不再像我们的next(err)那样自我logging。 它看起来太像一个正常的(即有效的)响应JSON发送。 此外,规范方法抛出的任何错误仍然会导致HTML输出。

这是Express'error handling中间件的地方。作为我的路线的一部分,我定义:

 app.use(function(err, req, res, next) { console.log('Someone tried to throw an error response'); }); 

我也将Error派生到一个自定义的JSONError类中:

 JSONError = function (status, message) { Error.prototype.constructor.call(this, status + ': ' + message); this.status = status; this.message = message; }; JSONError.prototype = Object.create(Error); JSONError.prototype.constructor = JSONError; 

现在,当我想在代码中抛出一个错误时,我会这样做:

 var err = new JSONError(404, 'Uh oh! Can't find something'); next(err); 

回到自定义error handling中间件,我将其修改为:

 app.use(function(err, req, res, next) { if (err instanceof JSONError) { res.status(err.status).json({ status: err.status, message: err.message }); } else { next(err); } } 

子类错误到JSONError是非常重要的,因为我怀疑Express对传递给next()的第一个参数进行了instanceof Error检查,以确定是否必须调用正常处理程序或error handling程序。 我可以删除instanceof JSONError检查,并进行小的修改,以确保意外的错误(如崩溃)也返回一个JSON响应。

你可以像这样使用它

 return res.status(400).json({'error':'User already exists.'}); 

如果你的目标是把它简化成一条简单的线,那么你可以依靠一些默认值。

 return res.end(res.writeHead(400, 'Current password does not match'));