(인프런) 김영한님의 모든 개발자를 위한 HTTP 웹 기본 지식을 공부하고 리뷰한 글입니다.
3. 3xx - 리다이렉션1
1. 3xx (Redirection)
요청을 완료하기 위해 유저 에이전트(웹 브라우저)의 추가 조치 필요
종류 | 상태코드 | 리다이렉트 시 | 사용 여부 |
영구 | 301 | 요청 메서드가 GET으로 변하고, 본문이 제거 될 수 있음 | 디폴트로 자주 사용 |
308 | 요청 메서드, 본문 유지 | 거의 사용X | |
일시 | 302 | 요청 메서드가 GET으로 변하고, 본문이 제거 될 수 있음 | 디폴트로 자주 사용 |
307 | 요청 메서드, 본문 유지 | 권장 | |
303 | 요청 메서드가 GET으로 변함 | 권장 | |
기타 | 300 | 사용X | |
304 | 자주 사용, 캐시 목적으로 사용 |
301=302, 308=307
2. 리다이렉션 이해
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)
- 사용자가 예전 이벤트 페이지 URL을 북마크 해두었는데 새로운 이벤트 페이지 URL로 바뀐 경우, 사용자가 예전 이벤트 페이지에 접속해도 새로운 이벤트 페이지 URL로 자동으로 접속할 수 있게 함
<자동 리다이렉트 흐름>

1) 클라이언트가 GET /event 를 서버에 요청한다.
2) /event 는 더이상 사용되지 않으므로 서버는 상태코드 301과 Location에 /new-event를 담아 응답한다.
3) 웹 브라우저에서 URL 경로를 /event -> /new-event 로 자동 리다이렉트 한다.
4) 클라이언트가 GET /new-event를 서버에 요청한다.
5) 서버는 상태코드 200과 /new-event에 대한 리소스를 응답한다.
<리다이렉션 종류>
1) 영구 리다이렉션: 특정 리소스의 URI가 영구적으로 이동
- 이벤트 페이지 URI가 바뀌어 더이상 사용하면 안되거나 내부적으로 URI 경로가 아예 바뀐 경우
e.g. /members -> /users
e.g. /event -> /new-event
2) 일시 리다이렉션: 일시적인 변경
- 주문 완료 후 주문 내역 화면으로 이동
- PRG: Post/Redirect/Get
3) 특수 리다이렉션: 결과 대신 캐시를 사용
3. 영구 리다이렉션 - 301, 308
리소스의 URI가 영구적으로 이동
- 원래의 URI를 사용X, 검색 엔진 등에서도 변경 인지
- 301과 308의 기능은 동일
1) 301 Moved Permanently
리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음(MAY)

- 클라이언트가 메세지 바디에 리소스를 담아 POST /event 를 서버에 요청하면
- 서버는 메세지 바디를 제거하고 301 코드와 Location에 /new-event를 담아 응답한다.
- 웹 브라우저의 URL이 자동 리다이렉트 되고
- 클라이언트는 메시지를 제거하고 GET /new-event 를 서버에 요청한다.
- 서버는 200 코드와 /new-event 의 리소스를 응답한다.
-> 이벤트 페이지에서 회원 정보를 등록하려고 했으나, 메시지 바디가 제거된 채로 자동 리다이렉트 되어 입력한 정보가 날라가 처음부터 회원 정보를 다시 입력해서 등록해야 한다.
2) 308 Permannet Redirect
리다이렉트시 요청 메서드와 본문 유지

- 클라이언트가 메세지 바디에 리소스를 담아 POST /event 를 서버에 요청하면
- 서버는 메세지 바디를 제거하고 308 코드와 Location에 /new-event를 담아 응답한다.
- 웹 브라우저의 URL이 자동 리다이렉트 되고
- 클라이언트는 메시지를 유지해서 POST /new-event 를 서버에 요청한다.
- 서버는 200 코드와 /new-event 의 리소스를 응답한다.
-> 이벤트 페이지에서 회원 정보를 등록하면 자동 리다이렉트 되어 입력한 정보가 유지되어 회원 정보가 정상 등록된다.
(참고) 여기서는 스펙 설명을 위해 이런 예제를 보여주었지만, 실무에서는 308을 거의 사용하지 않는다.
만약 /event 에서 /new-event로 URI가 바뀌면 내부적으로 전달해야하는 데이터 자체가 바뀌기 때문에, POST로 요청을 받아도 리다이렉트시 GET으로 바뀌는게 맞다.
4. 3xx - 리다이렉션2
1. 일시적인 리다이렉션 - 302, 307, 303
리소스의 URI가 일시적으로 변경
- 검색 엔진 등에서 URL을 변경하면 안됨
- 302, 307, 303의 기능은 동일
1) 302 Found
리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음(MAY)
2) 307 Temporary Redirect
리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안됨=MUST NOT)
3) 303 See Other
리다이렉트시 요청 메서드가 GET으로 변경(MUST)
2. PRG: Post/Redirect/Get
POST로 주문 후에 웹 브라우저를 새로고침하면 중복 주문이 될 수 있다. 이러한 경우, PRG를 사용한다.
- POST로 주문 후에 새로 고침으로 인한 중복 주문 방지
- POST로 주문 후에 주문 결과 화면을 GET 메서드로 리다이렉트
- 새로고침해도 결과화면을 GET으로 조회
- 중복 주문 대신에 결과 화면만 GET으로 다시 요청
(참고) 새로고침(Refresh)는 마지막에 요청한 request를 재요청하도록 정의하고 구현됨
1) RPG 사용전

1. 클라이언트가 마우스 1개를 POST로 주문 요청한다.
2. 서버는 주문 데이터(마우스 1개)를 DB에 저장한다.
3. 서버가 200 코드와 주문완료 html 리소스를 클라이언트에 응답한다.
4. 결과 화면을 새로고침하면 마지막 POST 요청을 새로고침 하게 된다.
5. 클라이언트가 마우스 1개를 POST로 중복 주문 요청을 한다.
6. 서버는 주문 데이터(마우스 1개)를 DB에 중복 저장한다.
7. 서버가 200 코드와 주문완료 html 리소스를 클라이언트에 응답한다.
-> 서버차원에서 중복 주문 방지: "잘못된 주문코드번호입니다"같은 응답으로 중복 주문을 방지해야 함
2) PRG: Post/Redirect/Get
-> 클라이언트차원에서 중복 주문 방지: PRG 이후 리다이렉트
- URL이 POST->GET으로 리다이렉트 되어 새로고침해도 GET으로 결과 화면만 조회

1~2. 위 과정과 동일
3. 서버가 302 코드와 Location에 /order-result/19를 담아 클라이언트에 응답한다.
4. 웹 브라우저에서 /order-result/19로 자동 리다이렉트한다.
5. 클라이언트가 GET으로 /order-result/19에 주문 결과화면을 요청한다.
6. 서버는 DB에서 19번 주문의 주문데이터를 조회한다.
7. 서버가 200 코드와 주문완료 html 리소스를 클라이언트에 응답한다.
8. 결과 화면에서 새로고침을 하면 마지막 GET요청을 새로 고침한다.
<302, 303, 307 정리>
1) 302 - 메서드가 GET으로 변할 수 있음
2) 307 - 메서드가 변하면 안됨
3) 303 - 메서드가 GET으로 변경됨
현실적으로 307, 303을 권장하지만 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용한다.
자동 리다이렉션 시에 GET으로 변해도 되면 302를 사용해도 큰 문제가 없다.
3. 기타 리다이렉션 - 300, 304
1) 300 Multiple Choices - 사용X
2) 304 Not Modified - 캐시 목적으로 사용
- 클라이언트에게 리소스가 수정되지 않았음을 알려줌 -> 클라이언트는 로컬PC에 저장된 캐시 재사용(캐시로 리다이렉트)
- 응답에 메시지 바디를 포함하면 안됨(로컬 캐시를 사용해야하기 때문)
- 조건부 GET, HEAD 요청 시 사용
6-3. 3xx(리다이렉션1) 질문 정리
Q.
6-4. 3xx(리다이렉션2) 질문 정리
Q. 상태코드를 개발자가 직접 지정하여 응답 메시지를 보내는 건가요? 그렇다면 어떻게 상태코드를 지정하나요?
백엔드 웹 프레임워크들은 보통 HTTP 상태 코드를 직접 지정할 수 있는 메서드를 제공한다.
response.setStatus(303)
[출처] https://www.inflearn.com/questions/112127
Q. 서버 측에서 동일 주문 중복 방지를 하기 위해 어떻게 구현해야하나요?
보통 주문 화면에 들어가는 시점에 서버에서 임시 주문 번호를 발급해두는데, 주문 번호는 다음과 같이 만들 수 있다.
1) DB가 제공하는 중복없이 순서대로 값이 증가하는 시퀀스 값을 사용
2) UUID 사용
[출처] https://www.inflearn.com/questions/117465
Q. 영구 리다이렉트와 일시 리다이렉트의 차이점은 무엇인가요?
단순 웹 브라우저 입장에서는 영구 리다이렉트와 일시 리다이렉트는 같다.
다만 검색엔진처럼 사용자가 아닌 시스템이 크롤링을 하는 경우를 생각해보면 도움이 된다.
1) 영구 리다이렉트는 검색 엔진이 URL을 변경해도 된다.
2) 일시 다이렉트는 검색 엔진이 URL을 변경하면 안된다. URL이 일시적으로 변경된 것으로 향후 다르게 변경될 수 있기 때문이다.
[참고] https://www.inflearn.com/questions/137142
[참고] https://www.inflearn.com/questions/189308
Q. 브라우저에서 POST 요청을 서버에 하고 클라이언트는 아직 302응답을 받지 못한 상황에서 새로고침을 하는 경우, 중복 주문을 막을 수 없는 건가요?
네. 302만으로는 중복 요청을 완전히 막을 수 없고 서버에서도 중복 요청시 해결방안을 마련해야 한다.
즉, 클라이언트 차원의 중복 요청 방지(PGR) & 서버 차원의 중복 요청 방지(중복된 주문 번호 체크) 모두 필요
[출처] https://www.inflearn.com/questions/181131
Q. 주문을 POST로 서버에 요청했을 때 1) 2xx와 함께 "주문완료"를 표현하는 정적 페이지로 응답하는 방법, 2) 3xx와 함께 PRG패턴을 적용해 리다이렉트 해주는 방법 2가지 중 실무에서 사용하는 응답 방법은 어떤 방식인가요?
결론은 리다이렉션을 사용하는 것이 더 나은 선택이다. 자세한 설명은 MVC 강의에서..
[출처] https://www.inflearn.com/questions/224361
'Spring > 모든 개발자를 위한 HTTP 웹 기본 지식' 카테고리의 다른 글
[모든 개발자를 위한 HTTP 웹 기본 지식] 07. HTTP 헤더1(일반헤더) - HTTP 헤더 개요, 표현 (0) | 2022.06.07 |
---|---|
[모든 개발자를 위한 HTTP 웹 기본 지식] 06. HTTP 상태코드 - 4xx(클라이언트 오류), 5xx(서버 오류) (0) | 2022.06.02 |
[모든 개발자를 위한 HTTP 웹 기본 지식] 06. HTTP 상태코드 - HTTP 상태코드 소개, 2xx(성공) (0) | 2022.06.02 |
[모든 개발자를 위한 HTTP 웹 기본 지식] 05. HTTP 메서드 활용 - HTTP API 설계 예시 (0) | 2022.05.30 |
[모든 개발자를 위한 HTTP 웹 기본 지식] 05. HTTP 메서드 활용 - 클라이언트에서 서버로 데이터 전송 (0) | 2022.05.30 |
(인프런) 김영한님의 모든 개발자를 위한 HTTP 웹 기본 지식을 공부하고 리뷰한 글입니다.
3. 3xx - 리다이렉션1
1. 3xx (Redirection)
요청을 완료하기 위해 유저 에이전트(웹 브라우저)의 추가 조치 필요
종류 | 상태코드 | 리다이렉트 시 | 사용 여부 |
영구 | 301 | 요청 메서드가 GET으로 변하고, 본문이 제거 될 수 있음 | 디폴트로 자주 사용 |
308 | 요청 메서드, 본문 유지 | 거의 사용X | |
일시 | 302 | 요청 메서드가 GET으로 변하고, 본문이 제거 될 수 있음 | 디폴트로 자주 사용 |
307 | 요청 메서드, 본문 유지 | 권장 | |
303 | 요청 메서드가 GET으로 변함 | 권장 | |
기타 | 300 | 사용X | |
304 | 자주 사용, 캐시 목적으로 사용 |
301=302, 308=307
2. 리다이렉션 이해
웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 자동 이동(리다이렉트)
- 사용자가 예전 이벤트 페이지 URL을 북마크 해두었는데 새로운 이벤트 페이지 URL로 바뀐 경우, 사용자가 예전 이벤트 페이지에 접속해도 새로운 이벤트 페이지 URL로 자동으로 접속할 수 있게 함
<자동 리다이렉트 흐름>

1) 클라이언트가 GET /event 를 서버에 요청한다.
2) /event 는 더이상 사용되지 않으므로 서버는 상태코드 301과 Location에 /new-event를 담아 응답한다.
3) 웹 브라우저에서 URL 경로를 /event -> /new-event 로 자동 리다이렉트 한다.
4) 클라이언트가 GET /new-event를 서버에 요청한다.
5) 서버는 상태코드 200과 /new-event에 대한 리소스를 응답한다.
<리다이렉션 종류>
1) 영구 리다이렉션: 특정 리소스의 URI가 영구적으로 이동
- 이벤트 페이지 URI가 바뀌어 더이상 사용하면 안되거나 내부적으로 URI 경로가 아예 바뀐 경우
e.g. /members -> /users
e.g. /event -> /new-event
2) 일시 리다이렉션: 일시적인 변경
- 주문 완료 후 주문 내역 화면으로 이동
- PRG: Post/Redirect/Get
3) 특수 리다이렉션: 결과 대신 캐시를 사용
3. 영구 리다이렉션 - 301, 308
리소스의 URI가 영구적으로 이동
- 원래의 URI를 사용X, 검색 엔진 등에서도 변경 인지
- 301과 308의 기능은 동일
1) 301 Moved Permanently
리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음(MAY)

- 클라이언트가 메세지 바디에 리소스를 담아 POST /event 를 서버에 요청하면
- 서버는 메세지 바디를 제거하고 301 코드와 Location에 /new-event를 담아 응답한다.
- 웹 브라우저의 URL이 자동 리다이렉트 되고
- 클라이언트는 메시지를 제거하고 GET /new-event 를 서버에 요청한다.
- 서버는 200 코드와 /new-event 의 리소스를 응답한다.
-> 이벤트 페이지에서 회원 정보를 등록하려고 했으나, 메시지 바디가 제거된 채로 자동 리다이렉트 되어 입력한 정보가 날라가 처음부터 회원 정보를 다시 입력해서 등록해야 한다.
2) 308 Permannet Redirect
리다이렉트시 요청 메서드와 본문 유지

- 클라이언트가 메세지 바디에 리소스를 담아 POST /event 를 서버에 요청하면
- 서버는 메세지 바디를 제거하고 308 코드와 Location에 /new-event를 담아 응답한다.
- 웹 브라우저의 URL이 자동 리다이렉트 되고
- 클라이언트는 메시지를 유지해서 POST /new-event 를 서버에 요청한다.
- 서버는 200 코드와 /new-event 의 리소스를 응답한다.
-> 이벤트 페이지에서 회원 정보를 등록하면 자동 리다이렉트 되어 입력한 정보가 유지되어 회원 정보가 정상 등록된다.
(참고) 여기서는 스펙 설명을 위해 이런 예제를 보여주었지만, 실무에서는 308을 거의 사용하지 않는다.
만약 /event 에서 /new-event로 URI가 바뀌면 내부적으로 전달해야하는 데이터 자체가 바뀌기 때문에, POST로 요청을 받아도 리다이렉트시 GET으로 바뀌는게 맞다.
4. 3xx - 리다이렉션2
1. 일시적인 리다이렉션 - 302, 307, 303
리소스의 URI가 일시적으로 변경
- 검색 엔진 등에서 URL을 변경하면 안됨
- 302, 307, 303의 기능은 동일
1) 302 Found
리다이렉트시 요청 메서드가 GET으로 변하고, 본문이 제거될 수 있음(MAY)
2) 307 Temporary Redirect
리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안됨=MUST NOT)
3) 303 See Other
리다이렉트시 요청 메서드가 GET으로 변경(MUST)
2. PRG: Post/Redirect/Get
POST로 주문 후에 웹 브라우저를 새로고침하면 중복 주문이 될 수 있다. 이러한 경우, PRG를 사용한다.
- POST로 주문 후에 새로 고침으로 인한 중복 주문 방지
- POST로 주문 후에 주문 결과 화면을 GET 메서드로 리다이렉트
- 새로고침해도 결과화면을 GET으로 조회
- 중복 주문 대신에 결과 화면만 GET으로 다시 요청
(참고) 새로고침(Refresh)는 마지막에 요청한 request를 재요청하도록 정의하고 구현됨
1) RPG 사용전

1. 클라이언트가 마우스 1개를 POST로 주문 요청한다.
2. 서버는 주문 데이터(마우스 1개)를 DB에 저장한다.
3. 서버가 200 코드와 주문완료 html 리소스를 클라이언트에 응답한다.
4. 결과 화면을 새로고침하면 마지막 POST 요청을 새로고침 하게 된다.
5. 클라이언트가 마우스 1개를 POST로 중복 주문 요청을 한다.
6. 서버는 주문 데이터(마우스 1개)를 DB에 중복 저장한다.
7. 서버가 200 코드와 주문완료 html 리소스를 클라이언트에 응답한다.
-> 서버차원에서 중복 주문 방지: "잘못된 주문코드번호입니다"같은 응답으로 중복 주문을 방지해야 함
2) PRG: Post/Redirect/Get
-> 클라이언트차원에서 중복 주문 방지: PRG 이후 리다이렉트
- URL이 POST->GET으로 리다이렉트 되어 새로고침해도 GET으로 결과 화면만 조회

1~2. 위 과정과 동일
3. 서버가 302 코드와 Location에 /order-result/19를 담아 클라이언트에 응답한다.
4. 웹 브라우저에서 /order-result/19로 자동 리다이렉트한다.
5. 클라이언트가 GET으로 /order-result/19에 주문 결과화면을 요청한다.
6. 서버는 DB에서 19번 주문의 주문데이터를 조회한다.
7. 서버가 200 코드와 주문완료 html 리소스를 클라이언트에 응답한다.
8. 결과 화면에서 새로고침을 하면 마지막 GET요청을 새로 고침한다.
<302, 303, 307 정리>
1) 302 - 메서드가 GET으로 변할 수 있음
2) 307 - 메서드가 변하면 안됨
3) 303 - 메서드가 GET으로 변경됨
현실적으로 307, 303을 권장하지만 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용한다.
자동 리다이렉션 시에 GET으로 변해도 되면 302를 사용해도 큰 문제가 없다.
3. 기타 리다이렉션 - 300, 304
1) 300 Multiple Choices - 사용X
2) 304 Not Modified - 캐시 목적으로 사용
- 클라이언트에게 리소스가 수정되지 않았음을 알려줌 -> 클라이언트는 로컬PC에 저장된 캐시 재사용(캐시로 리다이렉트)
- 응답에 메시지 바디를 포함하면 안됨(로컬 캐시를 사용해야하기 때문)
- 조건부 GET, HEAD 요청 시 사용
6-3. 3xx(리다이렉션1) 질문 정리
Q.
6-4. 3xx(리다이렉션2) 질문 정리
Q. 상태코드를 개발자가 직접 지정하여 응답 메시지를 보내는 건가요? 그렇다면 어떻게 상태코드를 지정하나요?
백엔드 웹 프레임워크들은 보통 HTTP 상태 코드를 직접 지정할 수 있는 메서드를 제공한다.
response.setStatus(303)
[출처] https://www.inflearn.com/questions/112127
Q. 서버 측에서 동일 주문 중복 방지를 하기 위해 어떻게 구현해야하나요?
보통 주문 화면에 들어가는 시점에 서버에서 임시 주문 번호를 발급해두는데, 주문 번호는 다음과 같이 만들 수 있다.
1) DB가 제공하는 중복없이 순서대로 값이 증가하는 시퀀스 값을 사용
2) UUID 사용
[출처] https://www.inflearn.com/questions/117465
Q. 영구 리다이렉트와 일시 리다이렉트의 차이점은 무엇인가요?
단순 웹 브라우저 입장에서는 영구 리다이렉트와 일시 리다이렉트는 같다.
다만 검색엔진처럼 사용자가 아닌 시스템이 크롤링을 하는 경우를 생각해보면 도움이 된다.
1) 영구 리다이렉트는 검색 엔진이 URL을 변경해도 된다.
2) 일시 다이렉트는 검색 엔진이 URL을 변경하면 안된다. URL이 일시적으로 변경된 것으로 향후 다르게 변경될 수 있기 때문이다.
[참고] https://www.inflearn.com/questions/137142
[참고] https://www.inflearn.com/questions/189308
Q. 브라우저에서 POST 요청을 서버에 하고 클라이언트는 아직 302응답을 받지 못한 상황에서 새로고침을 하는 경우, 중복 주문을 막을 수 없는 건가요?
네. 302만으로는 중복 요청을 완전히 막을 수 없고 서버에서도 중복 요청시 해결방안을 마련해야 한다.
즉, 클라이언트 차원의 중복 요청 방지(PGR) & 서버 차원의 중복 요청 방지(중복된 주문 번호 체크) 모두 필요
[출처] https://www.inflearn.com/questions/181131
Q. 주문을 POST로 서버에 요청했을 때 1) 2xx와 함께 "주문완료"를 표현하는 정적 페이지로 응답하는 방법, 2) 3xx와 함께 PRG패턴을 적용해 리다이렉트 해주는 방법 2가지 중 실무에서 사용하는 응답 방법은 어떤 방식인가요?
결론은 리다이렉션을 사용하는 것이 더 나은 선택이다. 자세한 설명은 MVC 강의에서..
[출처] https://www.inflearn.com/questions/224361
'Spring > 모든 개발자를 위한 HTTP 웹 기본 지식' 카테고리의 다른 글
[모든 개발자를 위한 HTTP 웹 기본 지식] 07. HTTP 헤더1(일반헤더) - HTTP 헤더 개요, 표현 (0) | 2022.06.07 |
---|---|
[모든 개발자를 위한 HTTP 웹 기본 지식] 06. HTTP 상태코드 - 4xx(클라이언트 오류), 5xx(서버 오류) (0) | 2022.06.02 |
[모든 개발자를 위한 HTTP 웹 기본 지식] 06. HTTP 상태코드 - HTTP 상태코드 소개, 2xx(성공) (0) | 2022.06.02 |
[모든 개발자를 위한 HTTP 웹 기본 지식] 05. HTTP 메서드 활용 - HTTP API 설계 예시 (0) | 2022.05.30 |
[모든 개발자를 위한 HTTP 웹 기본 지식] 05. HTTP 메서드 활용 - 클라이언트에서 서버로 데이터 전송 (0) | 2022.05.30 |