본문 바로가기
CS/네트워크

[HTTP] HTTP 상태 코드

by 2245 2023. 4. 20.

출처 

 

모든 개발자를 위한 HTTP 웹 기본 지식 - 인프런 | 강의

실무에 꼭 필요한 HTTP 핵심 기능과 올바른 HTTP API 설계 방법을 학습합니다., - 강의 소개 | 인프런


목차

     

        의미 종류
    1xx Information Code 요청이 수신되어 처리 중이다.  
    2xx Success Code 클라이언트의 요청을 성공적으로 처리했다. 200 : OK
    201 : Created
    202 : Accepted
    204 : No Content
    3xx Redirection Code 요청을 완료하기 위해 유저 에이전트의 추가 조치가 필요하다 300 : Multiple Choices
    301 : Moved Permanently
    302 : Found
    303 : See Other
    304 : Not Modified
    307 : Temporary Redirect
    308 : Permanent Redirect
    4xx Client Error Code 클라이언트의 오류 400 : Bad Request
    401 : Unauthoirzed
    403 : Forbidden
    404 : Not Found
    5xx Server Error Code 서버의 오류 500 : Internal Server Error
    503 : Service Unavailable

     

     

    상태코드란?

    클라이언트가 보낸 요청의 처리 상태를 응답 시 알려주는 코드입니다.

    • 1xx (Informational) : 요청이 수신되어 처리 중이다.
    • 2xx (Successful) : 요청 정상 처리되었다.
    • 3xx (Redirection) : 요청을 완료하려면 추가 행동이 필요하다.
    • 4xx (Client Error) : 클라이언트 오류 (잘못된 문법 등으로 서버가 요청을 수행할 수 없다.)
    • 5xx (Server Error) : 서버 오류 (서버가 정상적인 요청을 처리하지 못한다.)


    ❔ 만약, 웹 브라우저가 모르는 상태 코드가 생긴다면?

    • 클라이언트가 인식할 수 없는 상태코드가 반환된다면, 클라이언트는 상위 상태 코드로 해석하여 처리합니다.
    • 미래에 새로운 코드가 추가되어도 클라이언트를 변경하지 않아도 됩니다.
    • 예)
      • 299 ??? → 2xx (Successful)
      • 451 ??? → 4xx (Client Error)
      • 599 ??? → 5xx (Server Error)

     

    1xx (Informational)

    : 요청이 수신되어 처리 중

    • 거의 사용하지 않습니다.

     

    2xx (Successful)

    : 클라이언트의 요청을 성공적으로 처리

    • 200 : OK
    • 201 : Create
    • 202 : Accepted
    • 204 : No Content

     

    200 (OK)

    요청 성공

     

     

    201 (Created)

    요청을 성공하여 새로운 리소스가 생성되었습니다.

     

    • 201을 받은 클라이언트는 Location 헤더에 리소스 URL 이 포함되어 있음을 알 수 있습니다.

     

    202 (Accepted)

    요청이 접수되었으나 처리가 완료되지 않았다.

    • 예) 요청을 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리하는 경우입니다.

     

    204 (No content)

    요청이 성공적으로 수행되었으며 응답 바디에 보낼 데이터가 없다.

    • 클라이언트가 요청을 보내면 보통 서버는 응답 바디에 데이터를 담아 보냅니다.
    • 하지만, 보낼 데이터가 없을 경우에 204 코드를 리턴합니다.
    • 예) 웹 문서 편집기에서 문서를 수정 후 Save 버튼을 누르는 경우
      • 서버에서 요청을 받아 데이터를 저장을 완료 했으나 보낼 응답 데이터가 없어 보내지 않는 경우입니다.
      • 응답 내용이 없어도 204 메시지 (2xx)으로 성공을 인식할 수 있습니다.

     

    3xx (Redirection)

    요청을 완료하기 위해 유저 에이전트(클라이언트 프로그램 ex) 웹브라우저) 의 추가 조치가 필요하다.

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

     

    ❔ 리다이렉션?

    웹 브라우저는 응답 메시지 안에 3xx 상태 코드와 Location 헤더가 있다면, Location 위치로 자동으로 이동합니다. (리다이렉트)

     

    자동 리다이렉트 흐름

    예) 기존의 페이지가 새로운 URL로 변경된 경우

     

     

    1. 웹브라우저가 /event 로 요청을 보냅니다.
    2. 응답을 받은 서버는 경로가 바뀌어 301 상태 코드와 함께 Location 헤더에 변경된 새 URL(/new-event)을 담아 응답합니다.
    3. 응답을 받은 웹브라우저는 자동으로 바뀐 URL로 요청을 보냅니다.
    4. 바뀐 URL에서 정상 응답을 합니다.

     

    또 다른 예시로

    • 서로 다른 도메인을 갖는 두 개의 웹 페이지를 통합한 경우
    • 동일한 컨텐츠를 제공하는 여러 개의 URL을 하나의 URL로 통합한 경우

    가 있습니다.

     

    리다이렉션의 종류

    • 영구 다이렉션 (Permanent Redirect) : 특정 리소스의 URL이 영구적으로 바뀌어 더이상 변하지 않습니다.
      • ex) /event → /new-event
      • ex) /members → /users  (members를 더이상 쓰지 않고 users로 변경한 경우)
    • 일시 리다이렉션 (Temporary Redirect) : 바뀐 URL이 고정되지 않고 다시 다른 URL로 바뀔 가능성이 있습니다.
      • ex) 주문 완료 후 주문 내역 확인으로 이동 (PRG: Post/Redirect/Get)
    • 특수 리다이렉션 (Not Modified)
      • 응답 결과 대신 캐시를 사용하도록 연결하는 경우에 쓰입니다.

     

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

    • 리소스의  URL이 영구적으로 바뀌었다는 의미입니다.
    • 원래의 URL을 사용하지 않도록 검색 엔진 등에서 변경을 인지하여 이동합니다.
    • 301과 308 의 의미는 같으나 다음과 같은 차이점이 있습니다. 
    301 (Moved Permanently) 308 (Permanent Redirect)
    리다이렉트 시 요청 메서드를 POST로 보내도 GET으로 변경되거나 본문이 제거수도 있다. (Maybe) 리다이렉트 시 요청 메서드와 본문을 유지한다.
    (POST로 보내면 리다이렉트도 POST로 유지된다.)

     

    301

     

    • POST로 처음 요청이 발생했으나, 리다이렉트 시 GET으로 메소드가 변경되었습니다. 
    • 또한, 요청 메시지 바디도 제거되었습니다.

     

    308

     

    • 301과 달리 첫 요청의 메서드와 바디가 유지되었습니다.

     

     

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

    • 실무에서 많이 사용됩니다.
    • 리소스의 URI가 일시적으로 변경되었습니다. (변경되는 URL이 고정된게 아니라 다른 URL로 다시 변경될 수 있습니다.)
    • 세 302, 307, 303 코드의 의미는 같으나 다음과 같은 차이가 있습니다.
    302 (Found) 307 (Temporary Redirect) 303 (See Other)
     리다이렉트 시 요청메시지가 GET으로 변경되고 본문이 제거될 수 있습니다. (May be)
    (301과 비슷) 
    리다이렉트 시 요청 메서드와 본문을 유지합니다.
    요청 메서드를 변경하면 안됩니다. (Must Not)
    리다이렉트 시 요청 메서드가 GET으로 변경됩니다.

     

    활용 예시 : 만약 POST로 주문을 요청한 후 새로고침을 한다면?

    • 새로 고침은 웹 브라우저가 받은 요청을 한번 더 보냅니다.
    • 따라서 중복 주문이 될 수 있습니다.
    • 이 문제점은 PRG(Post/Redirect:Get) 으로 방지할 수 있습니다.

     

    PRG (Post/Redirect/Get)

    PRG 미적용

     

    • 같은 결과화면에서 새로고침을 한다면 사용자가 의도치 않게 주문을 2번하게 될 수도 있습니다.
    • 사실, 이런 경우엔 서버에서 막아야 합니다. 상품 고유 아이디를 만들어 이미 사용된 주문 번호라는 것을 인지함으로써 해결할 수 있습니다.
    • 하지만 클라이언트에서도 이를 방지하는 것이 좋습니다. 

     

     

    PGB 적용

     

    1. 주문을 요청 후 서버는 주문 정보를 DB에 저장 후 302 (Found)와 함께 Redirect할 Location URL을 담아 응답합니다.
    2. 웹브라우저는 302 코드와 Location 헤더를 확인하여 GET 으로 메서드를 변경하여 다시 변경된 URL로 요청을 합니다.
    3. 응답으로 받은 주문 완료 페이지가 웹브라우저에 띄워집니다. → 새로 고침을 해도 GET으로 완료 페이지만 조회됩니다.

     

    ❔ 그래서 어떤 것을 써야 하나요? 302, 307, 303

    • 302 Found → GET으로 변할 수도 있고 메시지 바디가 사라질 수도 있다.
    • 307 Temporary Redirect → 메서드와 메시지 바디가 변경되지 않는다.
    • 303 See Other → 메서드가 GET으로 변경된다.

     

    배경

    • 처음 302 가 제작될 때 의도는 HTTP 메서드가 유지되는 것이었습니다.
    • 하지만, 의도와 달리 웹 브라우저들이 대부분 GET으로 바꿔버렸습니다. (일부 웹 브라우저는 바꾸지 않는 것도 있다.)
    • 그래서 모호한 302 대신 307과 303이 등장했습니다. (301 대응으로 308이 등장한 이유와 같다.)

     

    현실

    • 307과 308을 권장하지만, 현실적으로 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용합니다.
    • 자동 리다이렉션 시 GET으로 변해도 된다면 302를 사용해도 큰 문제가 없습니다.

     

     

    기타 리다이렉션 : 300, 304

    • 300 Multiple choice : 사용하지 않습니다.
    • 304 Not Modified
      • 실무에서 많이 사용합니다.
      • 응답 결과 대신 캐시를 사용하도록 연결합니다.
      • 클라이언트가 로컬 캐시의 데이터 기간이 만료되어 서버에게 캐시의 생성일자 등과 같은 데이터를 전송하며 데이터를 요청할 경우, 서버가 리소스가 수정되지 않았으므로 응답 데이터없이 캐시 데이터를 그대로 사용하도록 연결하는 경우입니다.
      • 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용합니다. (캐시로 리다이렉트한다.)
      • 304 코드는 응답에 메시지 바디를사용하면 안됩니다. (로컬 캐시를 사용해야 하므로)
      • GET과 HEAD 요청 시에 304를 응답 코드로 사용합니다.  

     

     

    4xx (Client Error)

    클라이언트 오류

    • 클라이언트의 요청에 잘못된 문법 등으로 서버가 요청을 수행할 수 없습니다.
    • 오류의 원인이 클라이언트에게 있습니다.
    • 중요! 클라이언트가 이미 잘못된 요청, 데이터를 보내고 있기 때문에 똑같은 재시도는 실패합니다. (서버 오류는 클라이언트가 같은 요청을 보내도 서버의 에러 원인이 고쳐진다면 정상 동작할 수 있습니다.)

     

    400 Bad Request

    클라이언트가 잘못된 요청을 보내 서버가 요청을 처리할 수 없다.

    • 요청 구문, 메시지 등의 오류
    • 클라이언트는 요청 내용을 다시 검토하고 보내야 합니다.
    • 예) 요청 파라미터가 잘못되거나 API 스펙에 맞지 않을 때
      • 숫자를 보내야하는데 문자를 보내거나
      • 참고 : API 스펙 상의 오류는 백엔드 개발자들이 모두 막아야 합니다. 입구에서 스펙에 맞지 않는다면 400 에러로 돌려보내야 합니다. 500에러로 보내지면 안됩니다.

     

    401 Unauthorized

    해당 리소스에 대한 인증이 필요합니다.

    • 리소스 요청 시 필요한 인증(Authenticatoin)이 되지 않았습니다.
    • 401 오류 발생 시 서버는 응답에 WWW-Authenticate 헤더에 인증 방법을 포함시켜야 합니다.

     

    참고 : 인증 (Authentication) VS 인가 (Authorization)

    인증은 사용자가 누구인지 서버에서 확인이 되어야 합니다. (로그인)
    인가는 권한된 사용자만 접근을 허용하는 것입니다. (ADMIN 권한처럼 특정 리소스에 접근할 수 있는 권한)
    인증이 있어야 인가가 있습니다.

    하지만 오류 메시지가 Unauthorized 이지만 인증이 되지 않은 경우가 있습니다. (이름이 아쉬움) 

     

     

    403 Forbidden

    서버가 요청을 이해했지만 승인을 거부했다.

    • 주로 인증 자격은 증명했지만 접근 권한이 불충분한 경우입니다.
    • 예) 어드민 등급이 아닌 사용자가 로그인은 했지만 어드민 등급의 리소스에 접근한 경우입니다.

     

     

    404 Not Found

    요청 리소스를 찾을 수 없다.

    • 요청한 리소스를 서버에서 찾을 수 없다는 의미입니다.
    • 또는 클라이언트의 권한이 부족한 리소스에 접근할 때, 해당 리소스를 숨기고 싶을 때 사용합니다.

     

     

    5xx (Sever Error)

    서버 오류

    • 서버의 오류로 문제가 발생한 경우에 쓰입니다.
    • 서버에 문제가 있는 것이기 때문에 같은 요청을 재시도할 경우 성공할 수도 있습니다.
    • 예) NullpointerException, DB가 다운되거나 등
    참고 : 서버는 웬만하면 500대의 에러를 보내면 안됩니다,

    고객의 잔고가 부족하거나 20세 이상의 사용자가 주문을 해야 하는데 요청이 거부될 때 500에러를 보내는 경우가 가끔 있는데 500에러를 내면 안됩니다. 이 경우는 정상 프로세스입니다. (비지니스 상의 예외 케이스)
    500은 서버에 심각한 오류가 있다는 뜻이므로 DB가 다운됐거나 하는 심각한 오류가 아닐 시엔 사용하면 안됩니다.

     

    500 Internal Server Error

    서버 오류로 문제가 발생했다. 

    • 서버 내부 문제로 오류가 발생했을 때 사용됩니다.
    • 애매하면 500 오류를 사용하면 됩니다.

     

    503 Service Unavailable

    서비스 이용이 불가하다.

    • 서버가 일시적으로 과부하 또는 예정된 작업으로 인해 잠시 요청을 처리할 수 없을 때 사용됩니다.
    • Retry-After 헤더 필드로 얼마 뒤에 복구되는지 보낼 수도 있습니다.