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

时间:2013-01-04 09:24:12

标签: node.js express

我的node.js应用程序的建模类似于express/examples/mvc应用。

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

HTTP/1.1 400 Bad Request

但我想发送

HTTP/1.1 400 Current password does not match

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

我当前的解决方案控制器功能如下:

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;
  } 
  // ...
}

一切正常,但......似乎不是正确的方法。

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

9 个答案:

答案 0 :(得分:66)

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

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

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

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

然后使用curl验证其是否有效:

$ 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

答案 1 :(得分:50)

您可以查看res.send(400, 'Current password does not match') 查看express 3.x docs了解详情

Expressjs 4.x的更新

使用这种方式(看express 4.x docs):

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

答案 2 :(得分:11)

在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);

然后,您要在哪里创建错误'当前密码不匹配':

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

答案 3 :(得分:8)

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

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

客户端处理

<强>角: -

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

答案 4 :(得分:4)

您可以像这样使用

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

答案 5 :(得分:3)

我的用例是发送自定义JSON错误消息,因为我正在使用express来支持我的REST API。我认为这是一个相当普遍的情况,因此我会在答案中关注这一点。

简短版本:

Express Error Handling

  

定义错误处理中间件,就像其他中间件一样,除了   四个参数而不是三个,特别是签名(错误,   req,res,next)。 ...您最后定义了错误处理中间件   其他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响应,以及由附加堆栈跟踪的消息字符串组成的主体来处理此事。

例如,当我使用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'});

这就像一个魅力。也就是说,每次出现错误时都会发现输入非常笨拙,而且代码不再像我们next(err)那样自我记录。它看起来与正常(即有效)响应JSON的发送方式非常相似。此外,规范方法引发的任何错误仍会导致HTML输出。

这就是Express'错误处理中间件的地方。作为我的路线的一部分,我定义:

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

回到自定义错误处理中间件,我将其修改为:

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会对传递给instanceof Error的第一个参数进行next()检查,以确定是否必须调用普通处理程序或错误处理程序。我可以删除instanceof JSONError检查并进行微小修改,以确保意外错误(例如崩溃)也返回JSON响应。

答案 6 :(得分:2)

使用Axios时,您可以通过以下方式检索自定义响应消息:

Axios.get(“your_url”)
.then(data => {
... do something
}.catch( err => {
console.log(err.response.data) // you want this
})

...在Express中将其设置为:

res.status(400).send(“your custom message”)

答案 7 :(得分:1)

如果您的目标只是将其缩减为单行/简单行,您可以依赖默认值...

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

答案 8 :(得分:0)

在Restify中,我们应该使用SERIAL方法

语法是: ORDER BY id_image