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


89

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


4
음, 이것이 유일한 해결 방법 인 것 같습니다. 그러나 나는 그런 조언을하지 않을 것입니다. HTTP 1.1 사양에는 몇 가지 좋은 이유로 표준화 된 오류 설명이 있습니다. 사용자 지정 설명과 함께 잘 알려진 상태 코드를 보내는 것은 나쁜 습관이라고 생각하지만, 그것은 당신에게 달려 있습니다.
schaermu 2013 년

흠-그게 사실 일 수도 있습니다. 반면에 브라우저는 사람이 읽을 수있는 http 상태 메시지가 아닌 상태 코드 만 확인한다고 가정합니다. 가능한 경우 구체적인 (즉, 기본값이 아닌) 오류 메시지를 전송하기 위해 http 상태 메시지를 사용하는 것이 좋은 생각이라고 생각했습니다. 또한 클라이언트 측 자바 스크립트를 사용하여 쉽게 파악할 수 있습니다 (jQuery를 사용하면 "jqXHR.statusText"를 사용하여 표시 목적으로 오류를 얻을 수 있습니다)
lgersman

4
호환성이나 잠재적 인 브라우저 문제가 아니라 나쁜 습관 일뿐입니다.) 표시 할 오류 메시지를 원하는 경우 본문으로 전송하는 것이 의도 된 목적입니다.
schaermu

6
특정 오류 설명은 사양에 포함되지 않습니다. RCF-2616은 구체적으로 다음과 같이 명시합니다. "HTTP / 1.1에 대해 정의 된 숫자 상태 코드의 개별 값과 해당하는 이유 구문의 예제 세트가 아래에 나와 있습니다. 여기에 나열된 이유 구문은 권장 사항 일 뿐이며 다음으로 대체 될 수 있습니다. 프로토콜에 영향을주지 않고 로컬 등가물. "
Ted Bigham

사용자 지정 이유 구문은 훌륭하지만 (메시지가 "현재 암호가 일치하지 않습니다."이므로) 실제로 여기에 코드 401을 원하는 것처럼 들리며이 경우 메시지를 변경할 필요가 없습니다.
Codebling

답변:


59

자세한 내용은 이 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');

41
불행히도 이것은 http 상태 메시지를 설정하지 않지만 본문 내용으로 '현재 암호가 일치하지 않습니다'를 보냅니다 ...
lgersman

이것은 HTTP 상태를 설정하지만이 메서드 서명이 더 이상 사용되지 않기 때문에 경고를 발생시킵니다.
null 허용

1
res.status(400).send('Current password does not match');예제는 Express 4에서 저에게 적합합니다.
Tyler Collier

에서 작동Express ^4.16.2
아제

103

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

6
이것은 statusMessageStatusCode에 매핑 된 표준 메시지 이외의 다른 것으로 설정하는 올바른 방법입니다
peteb

4
다음을 사용하여 기본 개체의 속성을 가져올 수 있습니다.res.nativeResponse.statusMessage
sebilasse

@RobertMoskal 최소 Express 서버 (Express 4.16.1 및 Node 12.9.0)를 사용하여 테스트했으며 여전히 저에게 적합합니다. 애플리케이션 코드를 확인하세요. 다른 문제가있을 수 있습니다.
mamacdon

적어도 내가이 글을 쓰는 시점에서 이것이 해결책이기 때문에 이것이 왜 받아 들여지지 않는 대답이 아닌지 확실하지 않습니다.
Aaron Summers

12

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

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의 내장 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);
}

err.status = 400; 내가 믿는 것이 더 일반적입니다.
mkmelin

11

이렇게 사용할 수 있습니다

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

3

내 사용 사례는 내 REST API를 구동하기 위해 express를 사용하고 있기 때문에 사용자 지정 JSON 오류 메시지를 보내고 있습니다. 나는 이것이 상당히 일반적인 시나리오라고 생각하므로 내 대답에서 그것에 중점을 둘 것입니다.

짧은 버전 :

익스프레스 오류 처리

특히 서명 (err, req, res, next)을 사용하여 3 개 대신 4 개의 인수를 사용하는 것을 제외하고는 다른 미들웨어와 마찬가지로 오류 처리 미들웨어를 정의하십시오. ... 다른 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 서버로 사용할 때는 작동하지 않습니다. 오류가 HTML이 아닌 JSON으로 다시 전송되기를 원합니다. 또한 내 스택 추적이 내 클라이언트로 이동하는 것을 원하지 않습니다.

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 Errora next()에 전달 된 첫 번째 매개 변수 를 확인하여 일반 핸들러 또는 오류 핸들러를 호출 해야하는지 여부를 결정하기 때문입니다. instanceof JSONError확인을 제거하고 예기치 않은 오류 (예 : 충돌)도 JSON 응답을 반환하도록 약간의 수정을 수행 할 수 있습니다.


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

0

목표가 단일 / 간단한 라인으로 줄이는 것이라면 기본값에 약간 의존 할 수 있습니다.

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

-2

Restify의 경우 sendRaw()방법 을 사용해야 합니다.

구문은 다음과 같습니다. res.sendRaw(200, 'Operation was Successful', <some Header Data> or null)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.