HTTP 웹 지식

HTTP 상태 코드4(3xx - 리다이렉션2)

귀요미찰쓰 2022. 1. 11. 17:29
728x90
반응형
반응형

일시적인 리다이렉션(302, 307, 303)

- 리소스의  URI가 일시적으로 변경

- 따라서 검색 엔진 등에서 URI을 변경하면 안됨

- 실무에서 정말 많이 사용됨

- 302 Found

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

- 307 Temporary Redirect

      - 302와 기능은 같음

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

- 303 See Other

      - 302와 기능은 같음

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

 

 

302 307 303 기능은 모두 다 같다. 근데 모두 다 차이점이 있다. 그게 뭐냐면 302는 리다이렉트시 요청 메스다 GET으로 변하고, 본문이 제거가 될 수 있다. 근데 얘는 처음 스펙을 만들 때는 그냥 HTTP 메서드가 POST로 오면 POST 유지가 되고 그런 스펙을 생각했다. 근데 하지만 그게 디테일하게 스펙이 안 적혀있었다.

 

PRG:Post/Redirect/Get(일시적인 리다이렉션 - 예시)

- POST로 주문후에 웹 브라우저를 새로고침하면?

- 새로고침은 다시 요청

- 중복 주문이 될 수 있다.

 

 

PRG를 사용하기전에 관한 예제에 대해서 말하자면 제가 /order라는 페이지에 제가 만약에 주문을 합니다. 그러면 POST에다가 /order라고해서 URI 요청을 보내게되면요. 얘는 상품을 주문하는 것인데 HTML 폼에다가  itemid는 뭐고 count가 뭔지 적고 주문하기를 딱 누른다. 그냥 쉽게하기 위해서 itemId는 마우스로 해주고 count는 1로 해줬다. POST니까 서버가 가 받아서 상품 주문이 들어왔네 이러고 주문 데이터베이스에 마우스 하나를 저장해준다. 그리고 정상적으로 응답했다는 것을 알려주기 위해서 200 OK와 html안에 주문 완료를 보내줍니다.

그런데 만약에 혹시 실수로 여기서 새로고침 버튼을 누릅니다. 그러면 어떻게 되냐면 웹 브라우저가 POST 요청을 클라이언트에서 서버로 또 보내게 됩니다. 그러면 의도와 다르게 중복 주문을 하게 됩니다. 

 

PRG: Post/Redirect/Get(일시적인 리다이렉션 - 예시)

*그래서 위에 있는 문제점을 해결하기 위햏서 PRG 패턴을 사용하게 됩니다.

 

- POST로 주문후에 새로 골침으로 인한 중복 주문 방지

- POST로 주문후에 주문 결과 화면은 GET 메서드로 리다이렉트

- 새로고침해도 결과 화면을 GET으로 조회

- 중복 주문 대신에 결과 화면만 GET으로 다시 요청

 

 

처음에는 똑같습니다. 폼에다가 마우스를 입력하고 카운트를 입력한다음 상품 주문하기를 눌러주면 요청이 들어갑니다. 그러면 데이터베이스에 마우스 1개가 쌓이고 응답을 이제 줄것입니다. 응답 주는 부분이 중요합니다. 200 OK를 주는게 아니고 302 FOUND를 주는 것이다. 302 FOUND 말고도 303 See Other을 줘도 됩니다. 그러면서 Location 정보를 주게 됩니다. Location이 /order-result/19이것을 주문하게 되었을 때 그러면 클라이언트가 300시리즈가 왔고 Location도 왔으니 리다이렉트 하게 됩니다. 자 그려면 저거를 GET으로 바꿉니다. 그 다음에 /order-result의 19로 보내겠죠. 그러면 이번에는 주문 DB를 쌓는게 아니고 19번 주문을 조회해서 HTML 화면을 만듭니다. 그리고 200 OK를 보냅니다. 이제는 그러면 고객이 실수로 중간에 새로고침을 안하더라도 결과화면만 다시 요청을 하게 됩니다. 그래서 중복 주문 문제가 해결을 하게 됩니다.

PRG: Post/Redirect/Get(일시적인 리다이렉션 - 예시)

- PRG 이후 리다이렉트

       - URL이 이미 POST -> GET으로 리다이렉트 됨

       - 새로 고침해도 GET으로 결과 화면만 조회

 

 

그래서 뭘 써야 하나요?(302, 307, 303)

- 잠깐 정리

       - 302 Found -> GET으로 변할 수 있음(거의 계속 변한다)

       - 307 Temporary Redirect -> 메서드가 변하면 안됨

       - 303 See Other -> 메서드가 GET으로 변경

- 역사

       - 처음 302 스펙의 의도는 HTTP 메서드를 유지하는 것

       - 그런데 웹 브라우저들이 대부분 GET으로 바꾸어드림(일부는 다르게 동작)

       - 그래서 모호한 302를 대신하는 명확한 307, 303이 등장함(301 대응으로 308도 등장)

- 현실

       - 307, 303을 권장하지만 현실적으로 이미 많은 애플리케이션 라이브러리들이 302를 기본값으로 사용

       - 자동 리다이렉션에 GET으로 변해도 되면 그냥 302를 사용해도 큰 문제 없음

 

기타 리다이렉션(300, 304)

- 300 Multiple Choices: 안쓴다.

- 304 Not Modified(진짜 많이 쓴다)

      - 캐시를 목적으로 사용

      - 클라이언트에게 리소스가 수정되지 않았음을 알려준다. 따라서 클라이언트는 로컬PC에 저장된 캐시를 재사용한다.(캐시로 리다이렉트한다.)

      - 304 응답은 응답에 메시지 바디를 포함하면 안된다.(로컬 캐시를 사용해야 하므로)

      - 조건부 GET, HEAD 요청시 사용

 

반응형