如何在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'));
- 在Express 4和express-generator的/ bin / www中使用socket.io
- 如果我使用像express这样的节点服务器,是否需要webpack-dev-server?
- Node.js + express.js + passport.js:在服务器重启之间保持身份validation
- 使用Node.js将HTML转换为PDF
- 必须res.end()与node.js快速调用?
- 一个单元如何testingExpress的路线?
- node / express:使用Forever连续运行脚本时设置NODE_ENV
- 表示抛出错误为`body-parser deprecated undefined extended`
- req.body在post上为空