105

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

在控制器操作中,我想使用自定义 http 消息吐出 HTTP 400 状态。默认情况下,http 状态消息是“Bad Request”:

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 状态消息?

4

9 回答 9

134

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

你想要的是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
于 2016-04-08T19:18:24.057 回答
74

您可以查看此res.send(400, 'Current password does not match') Look express 3.x 文档以获取详细信息

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');
于 2013-01-04T11:47:43.527 回答
13

在 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 内置的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);
}
于 2013-01-05T17:38:10.010 回答
13

你可以像这样使用它

return res.status(400).json({'error':'User already exists.'});
于 2016-05-07T19:18:18.520 回答
11

在服务器端(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);
    }
});
于 2016-03-29T11:23:21.197 回答
5

使用 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”)
于 2020-08-11T19:51:36.753 回答
3

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

简洁版本:

快速错误处理

像其他中间件一样定义错误处理中间件,除了使用四个参数而不是三个参数,特别是使用签名(err、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。我也绝对不希望我的堆栈跟踪移到我的客户身上。

我可以使用例如发送 JSON 作为响应req.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);
  }
}

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

于 2015-10-15T06:57:05.000 回答
-1

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

return res.end(res.writeHead(400, 'Current password does not match'));
于 2015-05-30T00:37:21.670 回答
-2

那么在 Restify 的情况下,我们应该使用sendRaw()方法

语法是: res.sendRaw(200, 'Operation was Successful', <some Header Data> or null)

于 2019-01-02T09:10:49.703 回答