본문 바로가기

HTTP

[HTTP] HTTP 상태 코드

HTTP 상태 코드는 클라이언트가 보낸 요청에 대한 서버의 응답 결과를 나타내는 3자리 숫자 코드다.

이 코드를 통해 요청이 성공했는지, 실패했는지, 추가적인 작업이 필요한지를 알 수 있다.

 


1. 상태 코드 범위

1xx (정보) 요청이 수신되어 처리 중임.
2xx (성공) 요청이 정상적으로 처리됨.
3xx (리다이렉션) 추가 작업이 필요하거나 다른 URL로 이동됨.
4xx (클라이언트 오류) 클라이언트의 요청이 잘못됨.
5xx (서버 오류) 서버에서 요청을 처리하는 중 오류 발생.

 

🤨 만약 모르는 상태 코드가 나타나면?

  • 클라이언트가 모르는 상태 코드를 서버가 반환하면 어떻게 처리해야 할까?
  • 클라이언트는 상위 상태코드로 해석해서 처리하면 된다.
    • 299 → 2xx (Successful)
    • 451 → 4xx (Client Error)
    • 599 → 5xx (Server Error)
  • 따라서 미래에 새로운 상태 코드가 추가되어도, 클라이언트를 변경하지 않아도 된다.

 


2. 주요 상태 코드

200 OK 요청이 성공적으로 처리됨
201 Created POST 요청으로 새로운 리소스가 생성됨 (생성된 리소스는 응답의 Location 헤더 필드로 식별)
202 Accepted 요청이 접수되었으나, 완료되지 않음 (예: 요청 접수 후 1시간 뒤에 배치 프로세스가 요청 처리)
204 No Content 요청은 성공적으로 처리되었으나, 본문이 없음 (예: 웹 문서 편집기에서 저장 버튼)
301 Moved Permanently 리소스가 영구적으로 이동
302 Found 리소스가 일시적으로 이동
304 Not Modified
캐시된 리소스를 그대로 사용해도 됨
400 Bad Request 잘못된 요청 (문법 오류 등)
401 Unauthorized 인증 필요
403 Forbidden 접근 권한 없음
404 Not Found 요청한 리소스를 찾을 수 없음
500 Internal Server Error 서버 내부 오류
503 Service Unavailable 서버 과부하 또는 유지보수 중

 

 

 2.1. 1xx (정보 응답)

  • 요청을 정상적으로 받았으며, 처리를 계속 진행해야 한다는 뜻이다.
  • 일반적으로 클라이언트와 서버 간의 연결을 유지할 때 사용된다.
  • 거의 사용하지 않는다.
100 Continue 계속 진행 클라이언트가 요청을 계속해서 보내도 됨 (Expect: 100-continue)
101 Switching Protocols 프로토콜 변경 서버가 요청에 따라 다른 프로토콜로 변경함 (예: HTTP → WebSocket)
103 Early Hints 사전 정보 제공 정식 응답 전에 사전 정보(예: Link 헤더)를 제공

 

✔️ 100 Continue 예시

POST /upload HTTP/1.1
Host: api.example.com
Expect: 100-continue
HTTP/1.1 100 Continue

 

(서버가 100 Continue를 보내면 클라이언트는 요청 본문을 보냄)

 

 


 2.2. 2xx (성공 응답)

  • 요청이 정상적으로 처리되었다는 뜻이다.
200 OK 성공 요청이 정상적으로 처리됨
201 Created 리소스 생성됨 요청으로 인해 새로운 리소스가 생성됨
202 Accepted 요청 접수됨 요청을 받았으나, 즉시 처리되지 않음 (예: 배치 처리 같은 비동기 작업)
204 No Content 콘텐츠 없음 요청이 성공했으나, 응답 본문이 없음 (예: 웹 문서 편집기의 저장 버튼)

 

✔️ 201 Created 예시

POST /users HTTP/1.1
Host: api.example.com
Content-Type: application/json

{
  "name": "Alice"
}
HTTP/1.1 201 Created
Location: /users/123

(새로운 사용자가 id=123으로 생성됨)

 

 


 2.3. 3xx (리다이렉션 응답)

  • 요청을 완료하려면 클라이언트의 추가 조치가 필요하거나, 다른 URL로 이동해야 한다는 뜻이다.
  • 브라우저 또는 클라이언트가 새로운 URL로 요청을 변경하여 재시도하도록 유도한다.
  • 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)한다. 
301 Moved Permanently 영구 이동 요청한 리소스가 새로운 URL로 이동됨
302 Found 일시적 이동 요청한 리소스가 일시적으로 다른 URL에 있음
303 See Other 다른 URL 참조 POST 요청 이후 GET 요청을 수행하도록 유도
304 Not Modified 변경 없음 캐시된 리소스를 그대로 사용해도 됨
307 Temporary Redirect 임시 리다이렉트 302와 유사하지만 요청 메서드 유지
308 Permanent Redirect 영구 리다이렉트 301과 유사하지만 요청 메서드 유지

 

 

리다이렉션은 크게 영구(Permanent) 리다이렉션과 일시(Temporary) 리다이렉션로 구분되며, 각 상태 코드마다 요청 메서드와 본문 유지 여부, 브라우저/클라이언트의 처리 방식이 다르다.


1️⃣ 영구 리다이렉션

 

📌 301 Moved Permanently

  • 클라이언트가 요청한 리소스가 영구적으로 다른 URI로 이동했음을 나타낸다.
  • 이후 모든 요청은 새 URI로 해야 한다.
  • 브라우저는 자동으로 새 URI를 캐시하고, 검색 엔진도 링크를 새 URI로 갱신한다.
캐시 가능 여부 ✅ 가능 (브라우저와 검색 엔진이 기억함)
요청 메서드 유지  변경될 수도 있음 (전통적으로는 POST → GET으로 변경됨, 비표준적임)
요청 본문 유지  제거될 수도 있음
사용 예시 사이트 주소 변경 (http://example.com  https://example.com)

 

 

📌 308 Permanent Redirect

  • 301과 동일하게 영구 이동을 의미하지만, 반드시 요청 메서드와 본문을 그대로 유지해야 한다!
  • HTTP/1.1 이후에 등장한 정식 명세 기반의 영구 리다이렉션
캐시 가능 여부 ✅ 가능
요청 메서드 유지 ✅ 유지 (POST → POST, PUT → PUT)
요청 본문 유지 ✅ 유지
사용 예시 REST API에서 POST 요청을 다른 URI로 리다이렉트할 때

 


2️⃣ 일시 리다이렉션

 

📌 302 Found

  • 요청한 리소스가 일시적으로 다른 URI에 있음을 나타낸다.
  • 클라이언트는 기존 URI를 계속 사용해야 하며, 지금만 새 URI로 이동해야 한다.
  • HTTP/1.0에서는 원래 의미가 "Moved Temporarily"였으나, 브라우저가 POST를 GET으로 바꾸는 비표준 동작을 해 문제 발생함
캐시 가능 여부 🚫 불가
요청 메서드 유지 ❌ 보장되지 않음 (POST → GET이 되기도 함)
요청 본문 유지  제거될 수도 있음
클라이언트 동작 새 URI로 이동하되, 원래 URI는 계속 유지
사용 예시 로그인 후 홈 화면으로 리디렉션 등

 

 

📌 307 Temporary Redirect

  • 302과 동일하게 임시 이동을 의미하지만, 반드시 요청 메서드와 본문을 그대로 유지해야 한다!
  • 302의 비표준 동작을 바로잡은 HTTP/1.1 명세에 따른 상태 코드
캐시 가능 여부 🚫 불가
요청 메서드 유지 ✅ 반드시 유지
요청 본문 유지 ✅ 반드시 유지
클라이언트 동작 새 URI로 리다이렉션하되, 동일한 방식으로 재전송
사용 예시 유지보수 중 다른 서버로 일시 이동, POST 요청을 유지해야 할 때

 

 

📌 303 See Other

  • 요청이 성공적으로 처리되었으며, 결과는 다른 URI에 존재함을 명시
  • 반드시 GET 방식으로 새 URI를 요청하게끔 유도한다.
  • 웹에서 Form 제출 후 페이지를 새로고침할 때 중복 요청 방지를 위해 자주 사용된다.
캐시 가능 여부 🚫 불가
요청 방식 유지  GET으로 변경됨
주 사용처 PRG 패턴(Post → Redirect → Get)
사용 예시 게시글 작성 후 결과 화면으로 이동, 결제 완료 후 영수증 페이지로 이동 등

 


🔷 PRG 패턴과 303 See Other

 

PRG (Post → Redirect → Get) 패턴은 POST 중복 요청을 방지하기 위한 대표적인 웹 디자인 패턴이다.

303 See Other를 사용하면 POST 요청 후 GET 요청으로 변경되어 중복 요청을 방지할 수 있다.

 

🚨 문제점

사용자가 POST로 주문한 후, 브라우저를 새로고침하면 동일한 요청이 재전송된다!

 

💡 해결 방법

1. 클라이언트가 POST /orders 요청 (주문 요청)

2. 서버는 303 See Other 응답과 함께 Location: /orders/123 제공 (302 Found의 경우 GET으로 변경하면 된다.)

3. 클라이언트는 자동으로 GET /orders/123 요청

 

→ 사용자가 페이지를 새로고침해도 GET 요청만 반복되므로 중복 주문을 방지할 수 있다!

 


🔷 결론

  • 처음 302 Found의 의도는 요청 메서드를 유지하는 것
  • 그런데 웹 브라우저들이 대부분 GET으로 바꾸어버림
  • 그래서 모호한 302 대신, 명확한 307, 303이 등장 (301 대신 308도 등장)
  • 307, 303을 권장하지만, 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용
  • 자동 리다이렉션 시 GET으로 변해도 되면 그냥 302를 사용해도 큰 문제 없음

 


📌 304 Not Modified

  • 클라이언트에게 리소스가 수정되지 않았음을 알려준다.
  • 즉, 클라이언트가 이미 저장한 캐시 데이터를 그대로 사용해도 된다라는 뜻!
  • 따라서 클라이언트는 로컬 PC에 저장된 캐시로 리다이렉트한다.
  • 장점: 성능 최적화, 네트워크 트래픽 감소
  • 주의점: 로컬 캐시를 사용해야 하므로, 응답에 본문을 포함하면 안 된다!

 


🔷 3xx 리다이렉션 상태 코드 요약

상태 코드 의미 메서드 유지 사용 예
300 Multiple Choices 여러 개의 선택 가능 다양한 포맷 제공
301 Moved Permanently 영구 이동 도메인 변경
302 Found 일시적 이동 로그인 후 리다이렉트
303 See Other PRG 패턴 ❌ (GET으로 변경) POST  GET 요청
304 Not Modified 캐시된 데이터 사용 캐싱 최적화
307 Temporary Redirect 임시 이동 (메서드 유지) API 리다이렉트
308 Permanent Redirect 영구 이동 (메서드 유지) POST 유지 필요

 

 


 2.4. 4xx (클라이언트 오류)

  • 클라이언트의 잘못된 요청으로 인해 서버가 요청을 처리할 수 없음을 나타낸다.
  • 클라이언트가 이미 잘못된 요청을 보내고 있기 때문에, 재시도해도 실패함!
400 Bad Request 요청이 잘못됨 (예: JSON 형식 오류)
401 Unauthorized 인증이 필요함 (응답에 WWW-Authenticate 헤더와 함께 인증 방법을 설명)
403 Forbidden 요청이 거부됨 (접근 권한 부족)
404 Not Found 해당 리소스를 찾을 수 없음 (또는 접근 권한 부족)
405 Method Not Allowed 요청한 HTTP 메서드가 지원되지 않음

 

 


 2.5. 5xx (서버 오류)

  • 서버가 요청을 처리하는 중에 문제가 발생했음을 나타낸다.
  • 서버에 문제가 있기 때문에, 클라이언트가 재시도하면 성공할 수도 있다!
500 Internal Server Error 서버 내부 오류
501 Not Implemented 요청한 기능이 지원되지 않음
502 Bad Gateway 프록시 서버에서 잘못된 응답을 받음
503 Service Unavailable 서버가 과부하 상태이거나 유지보수 중 (Retry-After 헤더를 통해 복구 소요 시간 응답 가능)
504 Gateway Timeout 서버가 응답을 받을 수 없음

 

✔️ 503 Service Unavailable 예시

GET /service-status HTTP/1.1
Host: api.example.com
HTTP/1.1 503 Service Unavailable
Retry-After: 3600

(서버가 1시간 후 다시 요청하라고 안내)

 

 

'HTTP' 카테고리의 다른 글

[HTTP] HTTP 헤더  (0) 2025.04.07
[HTTP] 클라이언트가 서버로 데이터를 전송하는 방법  (0) 2025.04.06
[HTTP] HTTP 메서드  (0) 2025.04.06
[HTTP] HTTP 메시지  (0) 2025.04.06
[HTTP] HTTP의 주요 특징  (0) 2025.04.01