HTTP 상태코드

흔히 404 ERROR라고 하는 것을 많이 들어봤을 것이다.
클라이언트가 잘못된 URI 요청을 하면 404 Not Found 에러가 생기듯이
각 번호대로 뜻하는 바가 다르다.

  • 1xx(Informational) - 요청이 수신되어 처리 중 -> 현재는 잘 사용되지 않음
    (하드웨어가 발전됨에 따라 처리되는 시간이 빨라서 그런 듯 함.. 필자의 추측임)
  • 2xx(Successful) - 성공
    (요청을 정상적으로 처리하였음.)
  • 3xx(Redirection) - 리다이렉션
    (요청이 완료되기 위해 추가 행동이 필요하다.)
  • 4xx(Client Error) - 클라이언트 오류
    (클라이언트가 잘못된 문법으로 요청을 하여서 서버가 요청을 수행할 수 없음.)
  • 5xx(Server Error) - 서버 오류
    (서버가 잠시 중단이 되거나 서버의 문제가 생기면 서버에서 요청을 처리하지 못함.)

만약 모르는 상태 코드가 나타난다면 앞 번호만 보고 처리를 하면된다
예를 들어 295번 상태코드가 나타나면 정상 처리가 되었구나 라고 생각하고 설계하면 된다는 뜻이다.
477번 상태코드라면 클라이언트 오류라고 알고 있으면 되는 느낌 그래서 앞 번호가 가장 중요하다!

  • 상위 상태 코드로 해석해서 처리한다.라고 알고 있으면 된다.

1xx(Informational)

  • 요청이 수신되어 처리 중임.
  • 거의 사용하지 않고 있으므로 생략한다.
  • 김영한 강사님께서도 실무에서 본적이 없다고 하심..

2xx(Successful)

  • 성공적인 처리
  • 200 OK
  • 201 Created
  • 202 Accepted
  • 204 No Content

200 OK

  • 요청이 성공되었다.
  • 주로 GET 방식으로 무언갈 요청했을 때 성공적으로 요청이 되었고 그에 따른 응답으로 주로 쓰인다.

201 Created

  • 요청은 성공하였고 새로운 리소스가 생성되었다.
  • 주로 POST 방식의 요청을 하고 리소스가 정상 생성되면 응답할 때 201 Created 상태코드를 반환한다.
  • Location에 리소스의 경로가 나타난다. /members/100 이런 형식으로

202 Accepted

  • 요청은 접수되었다. 그러나 처리는 완료되지 않았다.
  • 요청은 접수되었지만 서버에서 1시간 뒤에 배치 프로세스가 요청을 처리한다면 202 Accepted가 반환된다.
  • 자주 쓰이지는 않는 상태코드이다.

204 No Content

  • 서버가 요청을 성공적으로 수행했다. 그러나 응답 페이로드 본문에 보낼 데이터가 없다.
  • 웹 브라우저 편집기에서 저장을 한다면 해당 편집 내용을 다시 서버에서 클라이언트에 보내줄 필요가 없고 같은 화면을 계속해서 보여줘야 한다. 해당 경우에는 204 No Content가 쓰이기도 한다.

200번 상태코드 정리

주로 사용하는 200번대 상태코드를 알아보았다.
이 외에도 정말 다양한 코드가 있지만 해당 코드에서도 200, 201 상태코드를 주로 사용하고 있다고 보면 된다. 또한, 200번대 상태 코드는 대부분 성공적인 처리라고 인식하면 되므로 모르는 코드가 나와도 개발자는 성공적인 처리가 되었음을 인지하고 개발하면 된다.


3xx(Redirection)

  • 요청을 완료하기 위해서는 유저가 추가적인 조치가 필요하다.
  • 그러므로 서버는 다시 클라이언트에게 추가 조치를 요청하기 위해 다시 반환한다.
  • 웹 브라우저는 3xx응답 결과에 Location 헤더가 있으면 Location위치로 자동으로 이동한다.(리다이렉트)

리다이렉트란?

이 또한 게시판을 만들어본 개발자라면 쉽게 알 수 있다.
나도 처음에 게시판을 만들때 위의 개념을 몰라서 글을 등록한 뒤 새로고침을 누르면
계속해서 이전에 등록했던 글이 등록되며 글이 증식했다.

그것을 방지하기 위해서 글을 등록하고 게시판으로 다시 돌아가면서(Location위치)
새로고침을 해도 글이 다시 등록되지 않게하는 방식이다.

이제 리다이렉트의 흐름에 대해 알아야하는데

  1. 클라이언트가 요청한다.(GET)
  2. 서버는 응답한다. Location 위치를 제공한다.
  3. 자동으로 리다이렉트가 되면서 클라이언트는 Location 위치로 이동한다.
  4. 클라이언트는 Location 위치의 uri를 서버에 다시 요청한다.(GET)
  5. 서버는 200 OK로 응답하며 해당 uri의 페이지를 보여주고 끝난다.

이 흐름이 매우 빠르기 때문에 클라이언트는 해당 과정을 전혀 인지하지 못한다.

리다이렉트의 종류

  • 영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동
  • 이는 경로가 완전히 바뀐 것을 의미한다.
    • 예) /members -> /users
    • 예) /event -> /new-event
  • 일시 리다이렉션 - 일시적인 변경
    • 주문 완료 후 주문 내역 화면으로 이동
    • PRG : Post/Redirect/Get
  • 특수 리다이렉션
    • 결과 대신 캐시를 사용

3xx 상태코드의 종류

  • 300 Multiple Choices
  • 301 Moved Permanently
  • 302 Found
  • 303 See Other
  • 304 Not Modified
  • 307 Temporary Redirect
  • 308 Permanent Redirect

301(Moved Permanently), 308(Permanent Redirect)영구 리다이렉션

  • 301과 308의 기능은 리소스의 URI가 영구적으로 이동했다는 것을 뜻하고 기능은 같다.
  • 리소스의 URI가 영구적으로 이동하였음.
  • 원래의 URI를 사용하지 않고 검색 엔진 등에서도 변경을 인지하고 있다.
  • 301 Moved Permanently
    • 리다이렉트시 요청 메서드가 GET으로 변하고 본문이 제거될 수 있음(MAY)
  • 308 Permanent Redirect
    • 리다이렉트 요청 메서드와 본문 유지(처음에 POST로 보냈다면 리다이렉트도 POST로 실행)

301(Moved Permanently)

  1. POST를 사용하여 서버에 요청하였다
  2. 영구 변경된 URI로 서버에서 응답한다.
  3. 자동으로 리다이렉트를 하여 GET으로 요청을 변경한다.
  4. 응답은 GET 200 OK가 실행된다. 그래서 입력했던 정보(본문)가 제거된 채로 보내진다.
  5. 결국 등록하고자 했던 정보는 전부 사라지고 GET으로 응답했으니 다시 클라이언트가 입력해야 하는 상황이 생기고 만다.

308(Permanent Redirect)

  1. POST를 사용하여 서버에 요청하였다.
  2. 영구 변경된 URI로 서버에서 응답한다.
  3. 자동으로 리다이렉트를 하여 POST로 다시 요청한다.
  4. 응답은 POST 201 Created가 실행된다. 입력했던 정보로 등록이 된다.

개발자가 의도했던 상황은 클라이언트가 서버에 POST로 요청했을 때
POST로 응답하길 원하지 않을까 라는 생각에서 308 Permanent Redirect를 제공하였으나
개발자들이 POST로 응답하지 않고 GET으로 응답하길 원하는 경우가 많아서
308 상태코드를 유도하지 않고 GET으로 반환하는 형식으로 개발을 많이 했다고 한다.
그래서 추가로 301 Moved Permanently를 만들었고 현재 301코드를 훨씬 많이 사용하고 있다고 한다.


302(Found), 307(Temporary Redirect), 303(See Other) 일시적인 리다이렉션

  • 리소스의 URI가 일시적으로 변경
  • 따라서 검색 엔진 등에서 URL을 변경하면 안됨.
  • 302(Found)
    • 리다이렉트 시 요청 메서드가 GET으로 변하고 본문이 제거될 수 있음.(MAY)
    • 301과 유사하지만 일시적, 영구적 리다이렉션이라는 점이 다르다.
  • 307(Temporary Redirect)
    • 리다이렉트 시 요청 메서드가 본문과 유지(요청 메서드가 변경되면 안된다.)(MUST NOT)
    • 308과 유사하지만 일시적, 영구적 리다이렉션이라는 점이 다르다.
  • 303(See Other)
    • 리다이렉트 시 요청 메서드가 GET으로 변경(MUST) 반드시 변경한다.
  • 303, 307 상태코드를 사용할 것을 권장하지만 실무에서는 302를 아직도 많이 사용하고 있다고 한다.

일시적 리다이렉션은 언제 사용하는가?

  • PRG 이것만 기억하자
  • POST로 요청 후 REDIRECT 한 뒤 GET으로 반환
  • POST로 요청을 한 뒤 새로고침을 했을 때 중복으로 등록 요청이 되지 않게 하기 위해
    GET으로 조회하고 마무리된다면 서버에서 페이지를 200OK로 응답해서 새로고침을 해도
    계속해서 200OK를 반환한다. 즉, 재요청해도 201 Created를 반환하지 않게 하는 방법인 것이다.
    새로고침을 해도 리소스가 생성되지 않게 하는 방식
  1. POST로 클라이언트가 서버에 요청
  2. POST 데이터를 저장
  3. 302Found로 서버에서 응답, Location도 함께 응답
  4. 자동 리다이렉트, Location으로 이동
  5. 클라이언트는 서버에서 응답받은 Location 경로를 GET으로 요청
  6. 서버에선 DB로 POST했던 데이터를 조회
  7. 서버에서 200 OK로 클라이언트에게 응답
  8. 결과 화면에서 새로고침을 해도 GET 200 OK로 응답되었기 때문에 변함 없이 계속해서 조회함.

302, 307, 303 중 어떤 것을 써야하는가?

  • 302 Found -> GET으로 변할 수 있다.
  • 307 Temporary Redirect -> 메서드는 변하면 안된다.
  • 303 See Other -> 메서드가 GET으로 변경된다.

일시적 리다이렉션의 역사

302스펙의 의도는 HTTP 메서드를 유지하는 것이었다.
그러나 웹 브라우저는 대부분 GET으로 바꾸기 때문에
모호한 302가 아닌 307, 303이 등장했다.(301 대응으로 308도 이 때 등장한다.)
그래서 307과 303을 권장하지만 이미 많은 애플리케이션 라이브러리에서 302를 기본값으로 사용한다.
자동리다이렉션 시 GET으로 변해도 된다면 302를 사용해도 큰 문제가 없다.


300(Multiple Choice), 304(Not Modify) 기타 리다이렉션

  • 300(Multiple Choice) : 김영한 강사님께서는 딱 3글자로 설명을 마치셨다. 안쓴다.
    그래도 알고 싶어서 찾아봤으나 자료도 많이 없고 모든 문서에서 잘 사용하지 않는다고 하였다.
    요청에 대해서 하나 이상의 응답이 가능한 코드를 뜻한다고 하는데 300번대 상태코드가 유저의 추가적 조치가 필요한 상태코드이므로 클라이언트가 복수의 응답 중 선택해야 하는 상황이라고 해석하였다.
  • 304(Not Modify) : 캐시를 목적으로 사용
  • 캐시에 있는 것을 가지고 리다이렉트 한다. 로컬 캐시를 가지고 리다이렉트 하기 때문에 메시지 바디가 없다.

4xx(Client Error)

  • 클라이언트 오류이다.
  • 클라이언트의 요청이 잘못되어 서버가 요청을 수행할 수 없는 상태이다.
  • 오류의 원인은 클라이언트에게 있다.
  • 중요한 것은 클라이언트가 잘못 요청하고 있기 때문에 여러번 재시도 해도 계속 실패한다.
    (복구 불가능하며 클라이언트가 요청을 수정해서 보내야한다.)

4xx 상태코드의 종류

  • 400 Bad Request
  • 401 Unauthorized
  • 403 Forbidden
  • 404 Not Found

400 Bad Request

  • 클라이언트가 요청을 잘못한 경우이다.(문자를 요청해야하는데 공백을 요청한다던지 등..)
  • 클라이언트는 요청 내용을 검토하고 다시 보내야한다.
  • 서버 개발자는 철저한 Validation을 통해서 스펙이 맞지 않으면 요청 자체를 튕겨내줘야한다.

401 Unauthorized

  • 클라이언트가 해당 리소스에 대한 인증이 필요하다.
  • 401 오류 발생시 응답 메시지에 WWW-Authenticate 헤더와 함께 인증 방법을 설명해야한다.
  • 참고
    • 인증(Authentication) : 본인이 누구인지 확인해야한다.(로그인)
    • 인가(Authorization) : 권한 부여(ADMIN 권한처럼 특정 리소스에 접근할 수 있는 권한, 인증이 있어야 인가가 있음.)
    • 오류 메시지가 Unauthorized 이지만 인증이 되지 않음.(이름이 아쉽지만 인증이다. 인가가 아님)

403 Forbidden

  • 클라이언트의 요청을 이해했지만 승인을 거부했다.
  • 기본적으로 접근권한이 없음을 뜻한다.
  • 일반 회원이 관리자 페이지에 요청을 하면 생기는 오류이다.

404 Not Found

  • 요청 리소스를 찾을 수 없다.
  • 요청 리소스는 서버에 없다.
  • 클라이언트가 권한이 부족한 리소스에 접근할 때, 403을 내지 않고 아예 리소스가 없다고 해당 리소스를 숨기고 싶으면 해당 상태 코드를 반환한다.

5xx(Server Error)

  • 서버 오류이다.
  • 서버가 모종의 이유로 인해서 장애가 생길 경우에 반환되는 상태코드이다.
  • 서버가 복구될 경우에 클라이언트가 똑같은 요청을 재시도 하면 성공할 수도 있다.

5xx 상태코드의 종류

  • 500 Internal Server Error
  • 503 Service Unavailable

500 Internal Server Error

  • 서버 내부의 문제가 생김.
  • 백엔드에서 발생한 오류는 대부분 500 에러를 반환한다.

503 Service Unavailable

  • 서비스 이용 불가
  • 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없음.
  • Retry-After 헤더 필드로 얼마 뒤에 복구되는지 예상 시간을 보낼 수도 있다.

5xx 에러 관련 정리

  • 503 에러는 흔치 않은 경우이다. 서버오류의 경우 예측하지 못한 상황에서 발생하는 경우가 많기 때문에 503 에러는 사실상 발생하지 않는 에러라고 보면 된다.
  • 사실상 500번대 에러는 만들면 안되는 에러이다.
  • 서버에서 문제가 터졌을 때만 한정적으로 500번대 에러를 만들어야한다.
  • 미성년자가 주류를 주문했다. 그럴 경우 500번대 에러가 아니라 400번대 에러를 발생시켜야 하는 것이다. 프로세스 자체는 정상이기 때문
  • 필자의 생각(500번대는 재실행했을 때 성공할 수도 있는 프로세스에만 500번대 에러를 발생시켜야 한다.)

길었던 HTTP 상태코드를 전부 정리하였다. 다음은 HTTP 일반 헤더에 대해 정리해보려 한다.

출처 : 모든 개발자를 위한 HTTP 웹 기본 지식(김영한 강사님 인프런 강의)

profile
비전공자 개발초보입니다!

0개의 댓글