development

노드 / 익스프레스에서 사용자 지정 http 상태 메시지를 보내는 방법은 무엇입니까?

big-blog 2020. 10. 26. 08:13
반응형

노드 / 익스프레스에서 사용자 지정 http 상태 메시지를 보내는 방법은 무엇입니까?


내 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 상태 메시지를 설정하는 더 좋은 방법이 있습니까?


기존 답변 중 어느 것도 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

자세한 내용은 res.send(400, 'Current password does not match')Look express 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');

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

서버 측 (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);
    }
});

이렇게 사용할 수 있습니다

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

My use-case is sending a custom JSON error message, since I'm using express to power my REST API. I think this is a fairly common scenario, so will focus on that in my answer.

Short Version:

Express Error Handling

Define error-handling middleware like other middleware, except with four arguments instead of three, specifically with the signature (err, req, res, next). ... You define error-handling middleware last, after other app.use() and routes calls

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

Raise errors from any point in the code by doing:

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

Long Version

The canonical way of throwing errors is:

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

By default, Express handles this by neatly packaging it as a HTTP Response with code 404, and body consisting of the message string appended with a stack trace.

This doesn't work for me when I'm using Express as a REST server, for example. I'll want the error to be sent back as JSON, not as HTML. I'll also definitely not want my stack trace moving out to my client.

I can send JSON as a response using req.json(), eg. something like req.json({ status: 404, message: 'Uh oh! Can't find something'}). Optionally, I can set the status code using req.status(). Combining the two:

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

This works like a charm. That said, I find it quite unwieldy to type every time I have an error, and the code is no longer self-documenting like our next(err) was. It looks far too similar to how a normal (i.e, valid) response JSON is sent. Further, any errors thrown by the canonical approach still result in HTML output.

This is where Express' error handling middleware comes in. As part of my routes, I define:

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

I also subclass Error into a custom JSONError class:

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;

Now, when I want to throw an Error in the code, I do:

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

Going back to the custom error handling middleware, I modify it to:

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

Subclassing Error into JSONError is important, as I suspect Express does an instanceof Error check on the first parameter passed to a next() to determine if a normal handler or an error handler must be invoked. I can remove the instanceof JSONError check and make minor modifications to ensure unexpected errors (such as a crash) also return a JSON response.


If your goal is just to reduce it to a single/simple line, you could rely on defaults a bit...

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

Well in the case of Restify we should use sendRaw() method

Syntax is: res.sendRaw(200, 'Operation was Successful', <some Header Data> or null)

참고URL : https://stackoverflow.com/questions/14154337/how-to-send-a-custom-http-status-message-in-node-express

반응형