본문 바로가기

study/HTTP

HTTP 웹 기본 지식(6) - HTTP 상태 코드

이 글은 인프런 김영한 님의 강의 모든 개발자를 위한 HTTP 웹 기본 지식을 듣고 정리하는 글입니다.

 

HTTP 상태 코드 : 클라이언트가 보낸 요청의 처리 상태를 응답에서 코드를 통해 알려주는 기능이다.

  • 100번대(Informational) : 요청이 수신되어 처리중이라는 뜻인데 거의 사용하지 않는다.
  • 200번대(Successful) : 요청이 정상적으로 처리된 경우.
  • 300번대(Redirection) : 요청을 완료하려면 추가 행동(Redirect)이 필요할  오는 응답이다.
  • 400번대(Client Error) : 클라이언트 오류. 잘못된 문법 등으로 서버가 요청을 수행할  없는 경우.
  • 500번대(Server Error) : 서버 오류. 서버가 정상 요청을 처리하지 못하는 경우.

만약 모르는 상태 코드가 나타나면? 예를 들어 275 라는 상태 코드를 받았다면, 200번대의 상태코드로 해석하여 처리하면 된다. 그래서 미래에 새로운 상태 코드가 추가 되더라도 클라이언트를 바꾸지 않아도 해석할  있다.

상태 코드를 자세히 알아보자.

 

먼저, 100번대 - 요청이 수신되어 처리중이라는 뜻인데 거의 사용하지 않는다.(과거 컴퓨터 성능을 생각해보면 왜 존재하는지 알 것 같기도 하다.)

 

200번대 - 클라이언트의 요청을 성공적으로 처리한 경우.

  • 200 OK - 요청이 성공적으로 처리됨
  • 201 Created - 요청이 성공해서 새로운 리소스가 생성되는 경우.(예를 들어 POST 새로운 멤버를 만들 ) 보통 응답 바디에 생성된 리소스의 Location 같이 준다.
  • 202 Accepted - 요청이 접수됐지만 처리는 완료되지 않은 경우. 배치 처리 같은 곳에서 사용한다.( 사용하지 않음)
  • 204 No Contented - 서버가 요청을 성공적으로 수행했지만, 응답 페이로드(본문, 바디)에 보낼 데이터가 없는 경우. 예를 들어 웹 페이지 에디터의 저장 버튼이나, 블로그를 작성할 때의 임시 저장 버튼 같은 느낌. 임시 저장을 버튼을 누른다고, 서버가 클라이언트에게 딱히 보낼 바디 데이터는 필요하지 않다.

그러면 이렇게 존재하는 상태 코드를 모두 사용하는 것이 좋을까?  그렇지는 않다. 모두 개별적으로 처리하는 것이 쉽진 않기 때문이다.

 

300번대 - Redirection. 요청을 완료하기 위해 user agent 추가 조치가 필요한 경우.

 브라우저는 300번대 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동으로 이동한다.

Redirection이 필요한 예) 이벤트 페이지가 있다고 하자. 그런데 시간이 지나서 이제 새로운 이벤트 경로가 생겼다고 하자. 그런데 이전에 공유된 옛날 이벤트 페이지로 들어가면 유효하지 않는 이벤트 페이지로 들어갈 것이다. 그래서 서버가 응답할  301 응답 코드를 주면서 헤더에 새로운 이벤트 페이지 Location 준다. 그러면 브라우저는 Location 경로로 새로 요청을 한다.

 

리다이렉션의 종류

  • 영구 리다이렉션 - 특정 리소스의 URI 영구적으로 이동하는 경우. 실제로 URI 변경된 경우.
  • 일시 리다이렉션 - 일시적인 변경. 예를 들어 주문 완료  주문 내역 화면으로 이동 시키는 경우.
  • 특수 리다이렉션 - 결과 대신 캐시를 사용.

 

  • 영구 리다이렉션 - 301, 308
  • 원래의 URL을 사용하지 않는 경우. 검색 엔진 등에서도 영구 리다이렉션은 변경을 인지한다.
  • 301 Moved Permanently. 리다이렉트  요청 메서드가 GET으로 변하고, 본문이 제거될  있다.(-> 처음 요청의 메소드와 본문이 유지되지 않을  있다는 뜻이다.) 그런데 거의  이렇게 구현되어 있다. 실제로 처음 HTTP 상태 코드를 설계할 때는 처음 보낸 메소드와 본문을 유지하도록 한 것이지만, 현재는 일반적으로 메소드를 GET으로 바꾸고, 본문을 제거한다.
  • 308 Permanent Redirect. 301과 기능은 같다. 그러나 리다이렉트 시, 요청 메서드와 본문이 유지 된다. 그런데 실무에서는 거의 이렇게 사용하지 않는다. 영구 리다이렉션을 한다는 것 자체가 이전의 본문도 유효하지 않다는 뜻이 되기 때문이다.

 

  • 일시적인 리다이렉션 - 302, 307, 303
  • 리소스의 URI 일시적으로 변경되는 경우. 그래서 검색 엔진 등에서 URL 변경하면 안된다.
  • 302 Found. 리다이렉트 , 요청 메서드가 Get으로 변경될  있고, 본문이 제거   있다.
  • 307 Temporary Redirect. 302 기능은 같은데 리다이렉트 , 요청 메서드와 본문을 유지한다.(요청 메서드는 변경되면 안된다. 절대 안된다.)
  • 303 See Other. 302 기능은 같은데 리다이렉트  요청 메서드가 Get으로 (무조건) 변경됨.

일시적인 리다이렉션의 예시 - PRG: POST/Redirect/Get

  • POST 주문 후에 서버가 200 OK 준다고 하자.
  • 서버의 응답 결과를 받은  브라우저를 새로고침하면? 새로고침은 다시 요청하는 것이다.
  • 200 OK를 받은 클라이언트의 URI는 그대로일 것이다. 그래서 새로고침을 한다면 중복 주문이   있다.
  • 이를 방지하기 위해선 POST 주문 후, 서버가 주문 결과 화면 URI GET 메서드로 리다이렉트 하도록 전달한다. 그러면 POST 이후 주문 결과 화면을 결과로 받을 것이고, 새로고침하더라도 결과 화면만 보게  것이다. 중복 주문을 막을  있다.
  • PRG 이후 리다이렉트: 요청 메서드는 POST에서 GET으로 바뀌고, 새로고침 하더라도 GET 요청으로 결과하면만 조회하게 됨.

그래서  써야 하는가?

  • 302 GET으로 변할  있다.
  • 307 메서드가 변하면 안된다.
  • 303 메서드가 GET으로 변경되어야 한다.
  • 원래 302 의도는 HTTP 메서드를 유지하는 것인데 대부분의  브라우저들이 GET으로 바꿔버렸다.(의도와 다르게) 그래서 모호한 302보다, 307, 303 등장했다.
  • 현실적으로 307, 303 권장하지만, 이미 많은 앱들이 302 기본으로 사용한다. 그래서 자동 리다이렉션 시에 GET으로 변해도 된다면 302 사용해도 문제는 없다.

 

  • 기타 리다이렉션 - 300, 304
  • 300 Multiple Choices: 안쓴다.
  • 304 Not Modified(특수 리다이렉션, 많이 사용함.) - 캐시를 목적으로 사용한다. 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용하게 된다.(캐시로 리다이렉트)
  • 304 응답은 메시지 바디를 포함하면 안된다.(로컬 캐시를 사용해야 하니까)
  • 조건부 GET, HEAD 요청 시 사용한다.(? 추후 강의에서 정리)

400번대 에러 응답 - 클라이언트 오류

  • 클라이언트의 요청에 잘못된 문법 등으로 서버가 요청을 수행할  없는 경우.
  • 오류의 원인이 클라이언트에 있다.
  • ### 중요! 클라이언트가 이미 잘못된 요청, 데이터를 보내고 있기 때문에, 똑같은 재시도가 실패한다.(서버 에러라면 재시도가 성공할 수도 있다. 근데 클라이언트 에러는 그렇지 않다.)

400 Bad Request - 클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할  없는 경우.

  • 요청 구문, 메시지 등등이 잘못된 경우
  • API 스펙이 맞지 않거나, 요청 파라미터가 잘못되는 경우
  • 클라이언트는 요청 내용을 다시 검토  보내야 한다.

401 Unauthorized - 클라이언트가 해당 리소스에 대한 인증이 필요한 경우

  • 인증이 되지 않은 경우
  • 401 오류 발생 시, 서버는 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명한다.

403 Forbidden - 서버가 요청을 이해했지만 승인을 거부한 경우.

  • 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우이다.

404 Not Found - 요청 리소스를 찾을  없는 경우.

  • 요청 리소스가 서버에 없을 
  • 또는 클라이언트가 권한이 부족한 리소스에 접근할  해당 리소스를 사용하기도 한다.

500번대 에러 응답 Server Error - 서버 오류

  • 서버 문제로 오류가 발생한 경우이다.
  • 서버에 문제가 있기 때문에 재시도 하면 성공할  있다.
  • 웬만해선 서버 에러를 만들면 안된다.
  • 예를들어 결제를 하려고 하는데 돈이 부족하다고 하자. 그런데 결제를 시도한다. 그렇다고 서버 오류를 반환하면 안된다.(이것은 비즈니스 에러다. 서버의 문제가 아니다.) 500 에러는 진짜 서버 에러로 생각해야 한다(비즈니스 로직에 의한 에러와는 상관 없는 것이다.)

500 Internal Server Error - 서버 내부 문제로 오류 발생. 애매하면 500 오류이다.

503 Service Unavailable - 서비스 이용 불가.

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