봄디의 개발일지
[HTTP] HTTP 상태코드 (100~500대 상태코드 총정리) 본문
1️⃣ 상태 코드
상태코드란 ? 클라이언트가 보낸 요청의 처리 상태를 응답에서 알려주는 기능입니다.
클라이언트가 서버로 요청을 보내면 그 요청이 잘 처리가 됐는지, 아니면 뭔가 문제가 있는지를 응답이 올 때 알려줍니다.
상태코드는 100, 200, 300, 400, 500 대로 크게 5가지로 나뉩니다.
- 1xx (Informational) : 요청이 수신되어 처리중 (거의 사용X)
- 2xx (Successful) : 요청 정상 처리
- 3xx (Redirection) : 요청을 완료하려면 추가 행동이 필요
- 4xx (Client Error) : 클라이언트 오류, 잘못된 문법 등으로 서버가 요청을 수행할 수 없음
- 5xx (Server Error) : 서버 오류, 서버가 정상 요청을 처리하지 못함
✅ 만약 모르는 상태 코드가 나타난다면 ?
클라이언트가 인식할 수 없는 상태코드를 서버가 반환하면, 클라이언트는 상위 상태코드로 해석해서 처리합니다.
미래에 새로운 상태 코드가 추가되어도 클라이언트를 변경하지 않아도 됩니다.
예를 들어 299 라는 상태코드를 서버가 반환하면, 2xx 로 생각하여 (Successful) 요청이 정상적으로 처리된 거라 생각하시면 됩니다.
2️⃣ 2xx (Successful) - 클라이언트 요청을 성공적으로 처리
- 200 OK
- 201 Created
- 202 Accepted
- 204 No Content
✅ 200 OK - 요청 성공
클라이언트가 GET 메서드로 /members/100 에 있는 리소스를 달라고 요청을 하면,
서버에서는 정상적으로 잘 처리를 해서 응답 할 때 HTTP 스타트 라인에 200 OK 를 내립니다.
✅ 201 Created - 요청 성공해서 새로운 리소스가 생성됨
클라이언트가 POST 메서드로 /members 위치에 { "username" : "young", "age" : 20 } 이라고 서버에 요청을 하면,
서버에서는 리소스를 생성하고 201 Created 상태코드를 통해 자원이 생성되었다는 것을 알려줍니다.
또한 새로 생성된 리소스 경로 (Location : /members/100) 를 넣어서 클라이언트로 응답을 합니다.
✅ 202 Accepted - 요청이 접수되었으나 처리가 완료되지 않았음
- 배치 처리 같은 곳에서 사용합니다.
- 예를 들어 요청 접수 후 1시간 뒤에 배치 프로세스가 요청을 처리하는 경우
✅ 204 No Content - 서버가 요청을 성공적으로 수행했지만, 응답 페이로드 본문에 보낼 데이터가 없음
예를 들어, 웹 문서 편집기에서 save 버튼을 누를 때, 아무 내용이 없어도 되고,
save 버튼을 눌러도 같은 화면을 유지해야 합니다.
위와 같은 경우 결과 내용이 없어도 204 메시지(2xx) 만으로도 성공을 인식할 수 있습니다.
3️⃣3xx (Redirection) - 요청을 완료하기 위해 유저 에이전트의 추가 조치 필요
- 300 Multiple Choices (거의 사용 X)
- 301 Moved Permanently
- 302 Found
- 303 See Other
- 304 Not Modified
- 307 Temporary Redirect
- 308 Permanent Redirect
Redirection 이란 ? 클라이언트가 서버에 요청을 했을 때 서버에서 요청을 완료하기 위한 추가적인 작업이 필요할 때 클라이언트에게 다시 보내는 것을 의미합니다.
리다이렉션을 좀 더 잘 이해하기 위해서 위의 그림을 가지고 설명하겠습니다.
기존 이벤트 창이었던 /event 가 /new-event 로 URL이 변경이 되었는데, 사용자가 /event 로 페이지를 들어가려는 경우,
GET 메소드를 통해서 서버한테 /event 에 대해 요청을 합니다.
주소가 변경되었기 떄문에 서버에서는 301 Moved Permanently 상태코드를 통해 주소가 옮겨졌다고
새로운 주소 (/new-event) 와 함께 응답을 합니다.
서버가 응답을 하면 새로운 주소인 new-event 로 자동 리다이렉트가 되고,
클라이언트가 GET 메서드와 함께 /new-event 에 대해 요청을 하고, 서버는 정상적으로 요청이 완료되었다고 200 OK 상태코드로 응답합니다.
리다이렉션은 크게 3가지의 종류로 나눌 수 있습니다.
- 영구 리다이렉션 - 특정 리소스의 URI 가 영구적으로 이동 (/members -> /users)
- 일시 리다이렉션 - 일시적인 변경 (주문 완료 후 주문 내역 화면으로 이동, PRG- Post/Redirect/Get)
- 특수 리다이렉션 - 결과 대신 캐시를 사용
✅ 영구 리다이렉션 - 301, 308
- 리소스의 URI 가 영구적으로 이동, 원래의 URL을 사용하지 않고 검색 엔진 등에서도 변경을 인지합니다.
- 301 Moved Permanently - 리다이렉션 시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있습니다.
- 308 Permanent Redirect - 301과 기능은 같음, 리다이렉트 시 요청 메서드와 본문은 유지됩니다.
✔ 301 Moved Permanently
/event 페이지가 /new-event 로 영구적으로 URL 이 변경 된 경우
POST 메서드를 통해서 name=hello&age=20 이라는 내용을 서버로 보내면, /event 라는 페이지는 더 이상 사용하지 않으므로 서버에서 301 Moved Permanently 상태코드를 새로운 주소와 함께 전달합니다.
301 은 redirect 요청 시, get으로 변하고 본문이 제거될 수 있는 특징을 가지고 있습니다.
301 상태코드가 오면 새로운 URL 인 /new-event 로 자동 리다이렉트가 되고, 기존에 POST 로 요청을 보냈지만,
GET 으로 변경된 상태로 서버에 요청합니다.
등록을 하기 위해 POST 로 기존에 보냈지만, redirect가 되어 GET으로 변경되었으므로 새로운 이벤트 페이지가 나오게 되면 다시 등록을 해야 하는 불편함이 있을 수 있습니다.
✔ 308 Permanent Redirect
308도 301 과는 동일하지만, 차이점이 자동 리다이렉트 된 후에 클라이언트에서 서버로 보낼 때 POST 를 유지시켜줍니다.
기본 동작 방식은 이러하지만, 실무에서는 거의 이렇게 사용하지 않고 /event 에서 /new-event 로 URL 이 바뀌면 내부적으로도 전달해야 하는 데이터 자체가 다 바뀌게 됩니다.
따라서 처음에 POST 로 전달이 와도, 리다이렉트가 된 후에는 GET 으로 다시 돌리는 것이 맞습니다.
308 뿐만 아니라 301 도 실무에서는 잘 사용되지 않고, 일시적 Redirection 을 많이 사용합니다.
✅ 일시적인 리다이렉션 - 302, 307, 303
일시적인 리다이렉션은 리소스의 URI 가 일시적으로 변경되는 것을 말합니다. 따라서 검색 엔진 드에서 URL 을 변경하면 안됩니다.
- 302 Found (리다이렉트 시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음)
- 307 Temporary Redirect (302와 기능은 동일, 리다이렉트 시 요청 메서드와 본문이 유지된다. - 요청 메서드를 변경하면 안된다)
- 303 See Other (302와 기능은 동일, 리다이렉트 시 요청 메서드가 GET으로 변경)
✅ PRG: Post/Redirect/Get
PRG 를 사용하지 않는 경우, 예를 들어 POST로 주문 후에 웹 브라우저를 새로고침하면 중복 주문이 될 수 있기 때문에
PRG 를 사용합니다.
PRG 를 사용하며 POST 로 주문 후에 새로 고침으로 인한 중복 주문을 방지할 수 있습니다.
POST 로 주문 후에 주문 결과 화면을 GET 메서드로 리다이렉트 시키기 때문에, 새로고침을 해도 결과 화면을 GET 으로 조회하게됩니다. 따라서 중복 주문 대신에 결과 화면만 GET으로 다시 요청합니다.
/order 에다가 주문을 한다고 가정할 때, POST 메서드를 사용해서 /order 에 URL 요청을 보내면 상품을 주문합니다.
itemId=mouse&count=1 이므로 마우스 1개를 서버가 받아서 주문데이터베이스에 마우스 하나를 저장합니다.
저장이 성공적임에도 불구하고 응답을 보낼 때 200 OK 를 보내는 것이 아닌 302 Found 혹은 303 See Other 인 상태코드와 함께 Location 정보를 같이 내려줍니다.
클라이언트는 300대 상태코드가 왔으므로 리다이렉트 한 후, GET 으로 메서드를 바꿔 서버로 요청합니다.
여기 페이지에서는 새로 고침을 잘못해서 눌러도 GET 으로 다시 요청이 들어가기 때문에 중복으로 주문이 되는 문제를 해결할 수 있습니다.
이렇게, PRG를 사용하면 사용성이 좋아지고, 서버 입장에서도 오류가 줄어든다는 장점이 있습니다.
302 307, 303 은 다 비슷한 역할을 하므로 307,303 을 권장하기는 하지만 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용하고 있기 때문에 자동 리다이렉션시에 GET 으로 변해도 되면 302를 사용해도 큰 문제가 없습니다.
✅ 기타 리다이렉션 - 300, 304
- 300 Multilple Choices (안쓴다)
- 304 Not Modified
- 304 는 캐시를 목적으로 사용하고, 클라이언트에게 리소스가 수정되지 않았음을 알려줍니다. 따라서 클라이언트는 로컬 PC에 저장된 캐시를 재사용합니다. 또한 304 응답은 응답에 메시지 바디를 포함하면 안됩니다. (로컬 캐시를 사용해야하기 때문)
- 304 는 조건부 GET, HEAD 요청 시 사용됩니다.
4️⃣ 4xx (Client Error) - 클라이언트 오류
클라이언트의 요청에 잘못된 문법 등으로 서버가 요청을 수행할 수 없는 경우 4xx 상태코드를 보내게 됩니다. 중요한 점은 오류의 원인이 클라이언트에게 있다는 점입니다. 클라이언트가 이미 잘못된 요청, 데이터를 보내고 있기 때문에 똑같이 재시도를 해도 계속 실패합니다.
- 400 Bad Request
- 401 Unauthorized
- 403 Forbidden
- 404 Not Found
✅ 400 Bad Request - 클라이언트가 잘못된 요청을 해서 서버가 요청을 처리할 수 없음
400 오류인 경우는 요청 구문, 메시지 등등의 오류가 발생했음을 나타냅니다.
따라서 클라이언트는 요청 내용을 다시 검토하고 보내야 합니다.
요청 파라미터가 잘못되거나, API 스펙이 맞지 않을 때 발생합니다.
✅ 401 Unauthorized - 클라이언트가 해당 리소스에 대한 인증이 필요함
401 오류는 인증이 되지 않을 때 발생합니다. 401 오류 발생 시 응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명합니다.
✅ 403 Forbidden - 서버가 요청을 이해했지만 승인을 거부함
403 오류는 주로 인증 자격 증명은 있지만, 접근 권한이 불충분한 경우에 발생합니다.
예를 들어 관리자 등급이 아닌 사용자가 로그인은 했지만, 관리자 등급의 리소스에 접근하려는 경우 발생합니다.
✅ 404 Not Found - 요청 리소스를 찾을 수 없음
404 오류가 가장 많이 볼 수 있는 오류 중 하나인데요, 요청 리소스가 서버에 없을 때 발생합니다.
또는 클라이언트가 권한이 부족한 리소스에 접근할 때 해당 리소스를 숨기고 싶을 때 발생합니다.
5️⃣ 5xx (Server Error) - 서버 오류
서버 오류는 서버 문제로 오류가 발생하는 경우를 말합니다.
서버에 문제가 있기 떄문에 재시도하면 성공할 수도 있습니다.
- 500 Internal Server Error
- 503 Service Unavailable
✅ 500 Internal Server Error- 서버 문제로 오류 발생, 애매하면 500 오류
✅ 503 Service Unavailable- 서비스 이용 불가
503 오류는 서버가 일시적인 과부하 또는 예정된 작업으로 잠시 요청을 처리할 수 없을 때 발생합니다.
Retry-After 헤더 필드로 얼마 뒤에 복구되는 지 보낼 수도 있습니다.
🔍 참고글
인프런 김영한 강사님의 [모든 개발자를 위한 HTTP 웹 기본 지식] 섹션 7. HTTP 상태코드 강의를 참고하여 작성했습니다.
'HTTP' 카테고리의 다른 글
[HTTP] HTTP 헤더 - 일반 헤더 (표현/협상) (4) | 2024.10.06 |
---|---|
[HTTP] HTTP 메서드 활용 (2) | 2024.09.29 |
[HTTP] HTTP 메서드 (GET, POST, PUT, PATCH, DELETE) (0) | 2024.09.29 |
[HTTP] HTTP 란 ? (0) | 2024.09.22 |
[HTTP] URI 와 웹 브라우저 요청 흐름 (0) | 2024.09.15 |