과거의 내가 미래의 나에게
HTTP 학습 (4-3) - 상태 코드(3xx번대) 본문
저번과 마찬가지로 요새 글 쓸 시간이 많이 없어서... 오늘도 300번대 상태 코드만 알아보고 글을 마무리할 것 같다.
3xx (Redirection): 요청을 완료하기 위해 추가 동작이 필요함
300번대 상태 코드는 리다이렉션을 나타내며 이는 클라이언트의 리퀘스트를 완료하기 위해서는 클라이언트가 요청한 리소스가 다른 곳에 있다던가, 서버가 요청을 처리하기 위해 추가 동작이 필요한 경우 등 리퀘스트가 정상적으로 처리를 종료하기 위해 브라우저 측에서 특별한 처리를 수행해야 할 때 사용된다.
■ 300 (Multiple Choice): 요청에 대한 응답이 하나가 아닌 둘 이상일 때를 나타낸다.
클라이언트가 HTTP 요청을 하였는데 해당 요청이 하나의 리소스가 아닌 둘 이상의 리소스를 가리킬 때, 서버는 그 리소스들의 목록과 함께 해당 상태코드를 넘겨 클라이언트에게 선택할 수 있도록 한다.
다만, 반환된 리소스들 중에서 하나를 선택하는 표준화된 방법이 없기에 실무에선 거의 사용되지 않는다고 한다.
■ 301 (Moved Permanently): 요청한 리소스가 다른 URI로 영구 변경되었음을 의미한다. 변경된 URI는 Location 헤더에 기록된다.
여기서의 변경된 것은 일시적으로 변경된 것이 아닌, 영구적으로 변경되었음을 의미하며, 브라우저는 해당 리소스로 연결되는 링크를 갱신하며 검색 엔진은 해당 리소스로 연결되는 링크를 갱신한다.
해당 상태코드는 일반적으로 GET 또는 HEAD 요청에 대한 응답으로 사용되는데, 301의 경우 브라우저가 리다이렉션 시 메서드를 보통 GET으로 하는 경우가 많기에, 괜히 처음 요청을 POST로 했다가 같이 보냈던 본문값이 제거되는 경우가 있을 수도 있기에 해당 상태코드 사용 시에는 GET과 HEAD 요청으로 사용하는 것이 좋다.
< 참조 >
301, 302, 303 상태 코드가 서버로부터 반환되면, 대부분의 브라우저에서는 POST를 GET으로 바꾸어서 기존 본문을 삭제한 후 재송신하게끔 되어있다. 301, 302에서 POST 메소드를 GET으로 변경하는 것을 금지하고있지만 대부분이 변경하도록 구현되어있다.다만 303의 경우는 리다이렉션 시 무조건 본문제거+GET요청으로 변경된다.
또한 다른 메서드는 서버의 리소스를 변경하려는 목적이 더 강하기에 리다이렉션보다는 클라이언트가 요청한 자료가 처리가 되었는지에 대한 결과가 더 적합할 것이다.
■ 302 (Found): 요청한 리소스의 URI가 일시적으로 변경되었음을 의미한다.
301 상태 코드는 아예 영구적으로 변경되었기에 후에 재요청 시 새로운 URI로 보내야하지만, 302 상태 코드의 경우 일시적으로 변경된 경우이니 기존의 URI로 요청해야 할 것이다.
301과 302의 구별실익은 사람보단 검색 엔진에게 있으며 어떤 리다이렉션을 쓰느냐에 따라 검색 엔진에 끼치는 영향이 크다. 301의 경우 영구적으로 옮겨졌기에 기존 URL과 관련된 모든 값이 새로운 페이지로 옮겨지고 검색엔진은 새로운 URL에서만 수집하게 된다. 302의 경우 임시적으로 옮겨졌기에 여전히 기존 페이지에 대한 정보를 수집하게 된다.
■ 303 (See Other): 클라이언트가 요청한 리소스는 다른 URI에서 얻어야 할 리소스라는 것을 의미한다.
303 상태코드는 리다이렉트 시 무조건 본문을 제거하고 요청 메서드로 GET을 사용한다. 따라서 클라이언트가 POST나 PUT 메서드로 요청에 대한 처리를 시키고 처리 결과를 별도의 URL에 GET 메소드로 리다이렉트 시키고 싶은 경우 사용되기도 한다.
■ 304 (Not Modified): 클라이언트가 이전에 요청했던 리소스가 서버에서 여전히 변경되지 않았다는 것을 의미한다.
304 상태 코드를 받으면 리소스는 여전히 최신 상태이니 캐시된 내용을 그대로 사용해도 된다라고 이해하면 된다.
304 상태 코드를 받기 위해서는 클라이언트가 if-Modified-Since 헤더와 같은 조건부 헤더를 사용한 요청을 해야만 하고 또한 GET과 HEAD 메서드에서만 가능하다.
304를 되돌려 줄 경우에는 클라이언트가 캐시된 내용을 써야하기에 리스폰스 바디에는 어떤 것도 포함되어 있어서는 안된다.
이 상태코드는 얼핏보면 다른 곳으로 이동시켜주는 리다이렉션과는 거리가 있어보이는데, 생각해보면 클라이언트는 서버에 요청했고 서버는 캐시된 서버로 가라는 답을 준 것이니 어찌보면 리다이렉션이라 할 수 있을 것 같다.
■ 305 (Use Proxy): 클라언트가 요청한 리소스에 접근하기 위해서는 프록시를 사용해야한다는 것을 의미한다.
보안 관련으로 더이상 사용되지 않는 상태코드이기에 짧게 하고 넘어간다.
■ 306 (Switch Proxy): 클라이언트에게 대체 프록시를 사용하도록 리다이렉션하는 것이다.
HTTP/1.1에 명시는 되어있지만 Unused로 정의되어있고 현재 사용되지는 않는다.
■ 307 (Temporary Redirect): 요청한 리소스의 URI가 일시적으로 변경되었음을 의미한다.
302와 동일한 의미를 가지고 있지만 차이점으로, 302는 POST로부터 GET으로 치환이 되어 본문을 잃어버리게 되지만, 307는 요청된 HTTP 메서드와 본문을 삭제시키지 않고 유지한다는 것이다. 즉, 클라이언트가 첫 요청으로 POST를 사용하여 본문을 함께 전송했다면 새로운 URL로 리다이렉션 시에도 해당 메서드와 본문이 유지되는 것이다.
■ 308 (Permanent Redirect): 요청한 리소스가 다른 URI로 영구 변경되었음을 의미한다.
301과 동일한 의미를 가지고 있지만 차이점으로, 302와 307과의 관계와 동일하다.
한 번 정리하자면 301과 308은 영구적 리다이렉션, 302과 307은 일시적 리다이렉션이고 301과 302는 메서드를 GET으로 변경하고 본문을 삭제시키며 307과 308은 메서드와 본문을 유지한다는 것이다.
영구적 리다이렉션 | 일시적 리다이렉션 | |
(리다이렉션 시) 메서드를 GET 변경 + 본문 삭제 |
301 | 302 |
(리다이렉션 시) 메서드 + 본문 유지 |
308 | 307 |
참고 문서
- 3XX (Redirection) 상태 코드 - 총정리 모음 - https://inpa.tistory.com/entry/HTTP-%F0%9F%8C%90-3XX-Redirection-%EC%83%81%ED%83%9C-%EC%BD%94%EB%93%9C-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0?category=980052
- HTTP Status Codes - https://http.dev/300