HTTP

HTTP 상태코드 (http 김영한)

ho코딩 2024. 1. 7. 14:52

저번 시간에 공부한 http 메서드에 이어 http 상태코드에 대해 알아보자. 

 

웹 페이지 개발을 조금이라도 건들여 본 사람이라면 프론트엔드와 백엔드 연동 시, 상태코드에 대해 접해본 적이 있을 것이다. 클라이언트 측에서 HTTP 요청 메시지를 보내면 , 서버에서 요청에 대한 처리를 하고 클라이언트에게 결과 응답 메시지를 보내준다.

 

이 경우 응답메시지 시작 부분에 200 과 같은 상태코드가 나타나는데 , 이 상태코드에 대해서 알고 있어야 

제대로 처리가 되었는지, 오류가 발생했는지 오류가 발생했다면 무슨 오류인지 알 수 있다.

 

 

 

크게 다음 5개의 상태코드로 나타낼 수 있다

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

구체적으로 xx에 다양한 숫자가 들어올 수 있는데, 가장 앞에 있는 숫자를 기준으로 상태를 대략적으로 짐작 할 수 있다. 

 

1xx 상태코드

 

1xx 코드는 클라이언트 측으로 부터 요청이 수신되었고, 서버에서 이를 처리중이라는 상태를 나타낸다. 

실무에서는 거의 보기 힘든 상태코드이므로 대략적으로 알고 넘어간다.

 

2xx 상태코드 

 

2xx는 큰 틀에서 보면 요청 및 처리에 성공했다는 상태코드이다. 

 

2xx를 더 세부적으로 나타내면 대표적으로 4개를 보일 수 있는데

  • 200 OK
  • 201 Created
  • 202 Accepted
  • 204 No Content

먼저 200 번은 요청 성공을 의미한다.

->클라이언트가 서버에 제대로 된 형식으로 요청했고 서버에서 잘 받아들었음을 의미. 주로 GET 메서드에서 나타남.

 

 

 

201번은 요청을 성공해서 새로운 리소스가 생성됨을 의미한다. 

201번

 

새로운 리소스를 생성한 경우 나타나므로, POST 메서드를 통한 요청에서 주로 반환되는 상태코드이다. 

 

이 경우에는 응답메시지에 리소스가 생성된 Location을 응답메시지에 넣어 클라이언트에게 반환한다. 

 

202번은 요청이 접수되었으나 처리가 완료되지 않았음을 의미하는 상태코드이다. 

- 배치 처리와 같은 곳에서 사용되고, 요청 접수 후 일정 시간 이후 배치 프로세스가 요청을 처리하는 경우 사용된다. 

 

 

204번은 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없는 경우 나타내는 상태코드이다. 

 

-예를 들면, 웹사이트 내 문서 편집기나 게시글 작성지 중간에 save 버튼을 누르는 경우이다. 

 save 버튼을 누르면 서버에서는 지금까지 작성한 문서에 대해서는 저장을 해야하지만, 클라이언트 측에 반환해줄 내용은 없다. 때문에 서버가 클라이언트에 반환할 내용이 없는 경우, "너가 보내준 요청은 잘 처리했어" 라는 의미를 가진 상태코드 204번을 반환한다.

 

200번 대에서는 주로 200 , 201이 사용되고 그 외는 실무에서 자주 사용되지는 않는다.

 

 

3xx 상태 코드

 

3xx번대 상태 코드는 주로 Redirection을 의미하고, 요청을 완료하기 위해 유저 에이전트의 추가 조치가 필요함을 말한다. 

 

웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)한다. 

 

예시를 보자면, 

리다이렉션 흐름

 

먼저 클라이언트가 서버에 /event에 GET 요청을 한다. 

하지만 서버는 더 이상 /event 엔드포인트를 사용하지 않고, /new-event 엔드포인트를 사용한다. 

 

그러면 클라이언트에게 "엔드포인트가 /new-event 로 바뀌었어!" 라고 알려주는 301 코드와 함께 

바뀐 Location 주소를 메시지에 담아 보내준다. 

 

클라이언트는 Location 주소가 담긴 메시지를 받고 , /new-event로 자동으로 리다이렉트되어 

아까 /event로 보낸 GET 요청을 다시 /new-event로 GET 요청을 한다. 

 

서버에서는 올바른 엔드포인트로 도착한 GET 요청을 인식하고. 처리해서 응답 메시지를 보내준다. 

 

리다이렉션에 대해서 더 자세히 이해해보자면 리다이렉션은 상황에 따라 

  • 영구 리다이렉션 - 특정 리소스의 URI가 영구적으로 이동한 경우 (예시 상황처럼 /event -> /new-event)
  • 일시 리다이렉션 - 일시적인 변경 (ex. 주문 완료 후 주문 내역 화면으로 이동) 
  • 특수 리다이렉션 - 결과 대신 캐시를 사용 

으로 나눌 수 있다. 

 

영구 리다이렉션 (301, 308번)

- 위 예시처럼 URI가 영구적으로 이동한 경우이다. 기존에 사용하던 URI를 사용하지 않고 변경한 경우. 

 

301번 -> 리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음. 

-301번은 리다이렉트시 처음에 보낸 요청 메서드가 GET이 아니더라도, GET으로 바꾸고 

  만약 POST 요청을 보냈다면, 그 내용이 제거 될 수도 있음을 이야기한다. 

301 리다이렉션 후 GET 요청으로 바뀜

 

308번 - > 리다이렉트시 요청 메서드와 본문을 유지 (301번과 차이점) 

-308번은 리다이렉트시 기존에 보낸 요청 메서드와 똑같이 리다이렉션 이후에도 서버에 다시 요청한다. 

301번의 경우에는 POST 요청을 한 후 리다이렉션을 했을 때 GET이 되었지만 

308번의 경우에는 POST 요청 후 리다이렉션 되어도 다시 POST 요청을 보낸다. 

308 리다이렉션 이후에도 POST 요청이 유지된다.

 

즉 301과 308은 리다이렉션 후 요청 메서드가 유지되느냐(308번) 유지되지 않고 GET으로 바뀌냐(301) 차이. 

 

 

 

일시적인 리다이렉션에는 302/307/303 코드가 있다. 

-리소스의 URL이 일시적으로 변경된 경우 

 

302번 - 리다이렉트시 요청 메서드가 GET으로 변하고(안 변할 수도) 본문이 제거될 수 있다. 

->모호한 상태코드지만 리다이렉션 후 요청 메서드가 GET으로 변할 수도 있고 아닐 수도 있다. (대부분 변함)

-> 본문 또한 삭제가 대부분 이루어지지만, 이루어지지 메서드가 변하지 않는다면 삭제가 되지 않는다. 

   

307번- 리다이렉트시 요청 메서드와 본문을 유지한다 

->302번의 모호한 GET으로 바뀔 수도 있고 아닐 수도 있는 부분 중, 바뀌지 않고 유지하는 것을 박아놓은 상태코드이다.

위에서 302번이 리다이렉션 후 요청 메서드가 GET으로 변경될 수도 있다고 했는데,

307번은 반드시 기존 메서드를 유지한다.  (ex) POST ->REDIRECTION-> POST)

 

303번 - 리다이렉트시 요청 메서드가 GET으로 변경된다

->307번과 마찬가지로 302번의 모호한 부분 중 반드시 리다이렉션 이후 GET요청으로 바뀌는 상태코드이다. 

->ex) POST ->REDIRECTION -> GET 

 

만약 상품을 주문을 하는 경우를 생각해보면, 

POST 요청을 통해 서버에 주문 요청을 한 후에 웹 브라우저를 새로고침 한다면

새로고침과 동시에 주문 요청한 POST가 다시 서버에 전송되며 "중복 주문"이 될 수 있다. 

 

불확실성을 감소하기 위해서 307 또는 303 코드를 쓰는게 이상적으로 보이지만 현실은 302를 더 많이 사용한다. 

 

RPG 사용 전 새로고침으로 인해 중복저장 됨.

이처럼 새로고침 또는 각 상황에서 재 요청시 중복될 수 있는 경우를 방지하기 위해 

PRG를 사용해야한다. (POST ->REDIRECTION->GET) 

 

PRG를 사용한 일시적인 리다이렉션

 

이처럼 새로고침 이후에도 중복 주문이 되지 않게 하기위해 상태코드 302번을 사용하여 

기존 요청 POST에서 리다이렉션 이후 GET요청을 함에 따라,

새로고침을 누른 경우에는 그저 POST요청한 주문 내역을 다시 보여주게 된다. 

 

일시적인 리다이렉션을 마지막으로 정리하자면 

  • 302번 -> 리다이렉션 이후 요청메서드가 GET으로 변할 수도 있고 아닐 수도 있다. 
  • 303번 -> 리다이렉션 이후 요청메서드가 GET으로 변경됨.
  • 307번 -> 리다이렉션 이후 요청메서드가 기존 요청으로 유지된다. 
  • 303/307이 불확실성이 없기 때문에, 이상적이지만 현실적으로는 302가 더 많이 사용된다. 

마지막으로 기타 리다이렉션의 경우에는 

  • 300번 Multiple Choices : 거의 사용되지 않는 코드.
  • 304번 Not Modified : 클라이언트에게 리소스가 수정되지 않았음을 알려주며 기존 캐시를 사용해도 됨을 의미. 

304번만 중점적으로 알고 있으면 되는데, 우리가 웹 브라우저에서 사이트를 요청할 경우 저번시간에 알려주었듯 

다운받아야할 것이 많다. (웹 페이지 하나에 표시되는 그림, 이미지, 글 등등) 

 

이를 매번 다운받기에는 다운로드 용량과 속도가 문제가 될 수 있어, 자주 사용되는 데이터를 일시적으로 로컬에 저장해두는 '캐시 저장소가 있다', 때문에 우리가 웹사이트 요청시 모든 부분을 매번 다운 받는게 아니라 로컬에 있는 캐시저장소에서 사용을 하고, 요청을 보내서 "내 캐시에 이런이런 데이터가 있는데 이거 그냥 써도돼?"라고 서버에 물어본다. 

 

만약 캐시 저장소에 가지고 있는 데이터와 서버에서 가지고 있는 데이터가 다르지 않다면, 서버에서 

304 상태코드를 보내주며, "응 내가 가지고 있는거랑 똑같은 거라 다운 안받고 그냥 캐시 저장소에 있는거 써도 돼" 라고 

알려준다.  이 경우 응답 메시지에서는 클라이언트에게 다시 응답할 메시지 바디는 비어져 있고 시작부분과 헤더부분만 있다.

 

4xx 상태코드

 

4xx 상태코드는 간단히 말하면 클라이언트가 서버에 요청을 잘못된 형식으로 보낸 경우의 에러 메시지이다. 

 

즉, 오류의 원인은 클라이언트에게 있음을 이야기한다. 

웹 개발의 관점에서 보면 프론트엔드가 사용자로 부터 요청을 잘못된 형식으로 받아서 서버에게 보낸것이다. 

(알아듣기 쉽게 얘기하자면, 서류 형식을 잘못 만들어서 사용자에게 입력을 받고 제출한 셈) 

(그러므로 서류 형식(프론트엔드)를 다시 제대로 만들어야한다.) 

 

종류에는 

  • 400번 -> BAD Request 요청 구문, 메시지 등등 오류 , 요청 내용을 다시 검토하고 보내야한다. 
  • 401번-> Unauthorized 인증되지 않음, 클라이언트가 해당 리소스에 대한 인증이 필요함.  
    • 인증(Authentication) : 본인이 누구인지 확인 (로그인 오류)
    • 인가(Authoriztion): 로그인 이후 권한을 부여한 경우 (관리자 권한? 사용자 권한?)
  • 403번 -> 서버가 요청을 이해했지만 승인을 거부당함, 인증 자격은 있지만 접근 권한이 불충분
    • 사용자 권한으로 로그인 한 후 관리자 페이지를 요청한 경우. 
  • 404번 -> 요청 리소스가 서버에 없음 or 클라이언트가 권한이 부족한 리소스 접근시 해당 리소스를 숨기고 싶을 때
    • Dropbox와 같은 곳에서 많이 봤을 상태코드, 리소스를 요청했지만 요청한 곳에 리소스가 없을 경우.
    • 또는, 사용자 권한의 사용자가 관리자 권한의 리소스를 요청했지만 서버에서 이를 숨기고 싶을 때.

 

5xx 상태코드

 

500번대의 상태코드는 서버 문제로 인한 오류발생을 나타내는 상태코드이다. 

때문에, 재시도(재요청) 하는 경우 성공할 수도 있다.

 

  • 500번 : 서버 내부 문제로 오류 발생 (애매하면 500번)
  • 503번: 서비스 이용불가, 일시적인 과부하 일시점검 등으로 인한 요청처리 불가 
    • Retry-After 헤더 필드에 얼마뒤에 복구되는지 응답메시지로 보낼 수 있다.