3xx (Redirection) 2

김원종·2023년 9월 26일
0

일시적인 리다이렉션 302 , 307 , 303
희망하기는 307 303을 사용하길 희망하지만 실무에서는 302를 많이 사용하고 있다!!
대부분 프레임 워크나 기술레벨들에서 보면 라이브러리들이 리다리엑트하면 디폴트로 302를 많이 사용하고 있다 . 그렇기 때문에 굳이 302를 그냥 GET으로 변경해도 되는 상황이면 302를 사용해도 크게 문제는 없다!

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

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

  • 302 Foun ( 영구 리다이렉션 상황과 똑같다! 대부분 GET으로 다 바꿈 하지만 명확하지 않다 !)

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

    • 302와 기능은 같음
    • 리다이렉트시 요청 메서드와 본문 유지(요청 메서드를 변경하면 안된다. MUST NOT )
  • 303 See Other (명확하게 GET으로 변경)

    • 302와 기능은 같음
    • 리다이렉트시 요청 메서드가 GET으로 변경

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

    웹 애플리케이션을 처음 개발하다보면 이것을 꼭 한번은 맞닥뜨린다 그걸 PRG라고 한다.

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

  • 새로고침은 다시 요청

  • 중복 주문이 될 수 있다.

    **만약 포스트로 결제와 관련된 상품을 주문페이지에서 폼을 입력하고 주문하기를 누르면 POST로 내 데이터가 넘어갈것이다. 그런 상태 즉 결과가 남아있는 상태에서 웹브라우저를 새로고침하면?? 물론 경고창을 보내겠지만 포스트에 데이터가 한번더 들어가서 서버에 중복 주문이 들어갈수 있다. 새로고침도 포스트가 되버린것이다. 왜냐 마지막에 내가 포스트를 보내기 때문에 웹브라우저도 내가 새로고침을 하면 그 폿그트 요청을 한번더 하는것이다. 그것을 해결하려면 !? 아래 그림과 같다!!

  • PRG 사용전에는

  1. /order 페이지에 주문을 한다. itemId 와 count를 입력하고 주문하기를 클릭한다.
  2. POST로 서버가 받아서 주문 데이터베이스에 마우스 하나를 저장한다.
  3. 클라이언트에게 200OK응답을 보내고 주문완료 html을 보낸다 . 그럼 마지막 요청인 POST가 남아있는다.
  4. 그 상태에서 새로고침을 누르면 웹브라우저가 마지막요청을 새로고침 즉 다시 요청하는것이기에 post요청을 또 서버로 보낸다.
  5. 서버는 똑같이 데이터베이스에 마우스 하나를 저장한다.
  6. 그럼 총 마우스는 2개가 되어 중복주문이 되는 상황이 발생한다.
    [ 물론 이런 상황은 서버에서 미리 막아야하는 상황은 맞다. 상품아이디 같은걸 미리 만들어 놓고 중복 주문이 오면 잘못된 상품 주문번호 즉 이미 사용된 주문번호라고 알려주는등의 방식을 사용해서 막아줘야한다 ]
  • 클라이언트에서의 방지법
    - POST로 주문후에 새로 고침으로 인한 중복 주문 방지
    - POST로 주문후에 주문 결과 화면을 GET 메서드로 리다이렉트
    - 새로고침해도 결과 화면을 GET으로 조회
    - 중복 주문 대신에 결과 화면만 GET으로 다시 요청
  • PRG를 사용하면
  1. /order 페이지에 주문을 한다. itemId 와 count를 입력하고 주문하기를 클릭한다.
  2. POST로 서버가 받아서 주문 데이터베이스에 마우스 하나를 저장한다.
  3. 응답을 200OK가 아니라 302Found 혹은 303 SeeOther을 보내면서 Location 정보를 준다.
  4. 응답을 받은 클라이언트는 응답코드를 보고 자동 리다이렉트가 실행된다.
  5. 그럼 Location에 입력된 정보로 이동된다.
  6. 그 상황에서 새로고침을 하면 마지막 남은 GET을 사용해 19번 주문 정보를 조회해서 화면을 만들어준다.
  • PRG 이후의 리다이렉트
    • URL이 이미 POST -> GET으로 리다이렉트 됨
    • 새로 고침 해도 GET으로 결과 화면만 조회
      [ 이렇게 사용하면 사용성이 좋다. 사용자 입장에서도 실수로 새로고침을 하더라도 결과POST에서 새로고침하면 보이는 경고창도 안보여 화면이 깔끔하게 보이는거고 그리고 서버 입장에서도 오류가 줄어든다 . ]

그래서 뭘 써야하나요? 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 요청시 사용
profile
개린이

0개의 댓글

관련 채용 정보