본문 바로가기
공부 기록

양식 다시 제출 확인 팝업창

by 매트(Mat) 2022. 1. 14.

개발을 하면서 어드민 페이지에서 ‘새로고침’이나 ‘뒤로가기’를 눌렀을 때 아래와 같은 팝업창이 나와서 당황했습니다.

양식제출확인

그렇다면 왜! 이러한 팝업창이 뜬걸까??

원인은 간단합니다.

원인이 뭘까??

바로 post 방식을 사용했기 때문입니다.

  • form submit()으로 post 요청을 하고 리다이렉트를 하지 않으면 새로고침시 똑같은 url 주소로 post 요청을 하기 때문에 "정말 이대로 다시 post 요청할 것인지" 물어보는 것입니다.
    • 제 개인적인 추측이지만 post 요청의 경우에는 민감한 데이터를 담고 있기 때문에 재요청시 정말로 다시 post 요청할 것인지 물어보는 것 같습니다.
  • redirect가 아닌 forward를 해도 같은 팝업창이 발생할 수 있습니다.

잠깐 개념을 살펴보자.

검색이나 페이지 이동할 때는 주로 Get을 사용합니다.

그 이유는 어딘가로 이동할 때는 주소창에 데이터를 보여줘도 보안상 문제가 없기 때문이죠.

또한 검색이나 이동할 때는 Get을 쓰는게 성능적으로 더 좋습니다.

하지만 만약에!

검색할 때조차 URL에 정보가 드러나는게 싫다!

이러면 post 방식을 사용해야 하는데요.

post 방식은 뭐죠? → 메시지 바디에 데이터를 담아서 요청합니다.

자, 검색 예를 들어보죠.

Get 요청

Get 요청을 할 경우에는 데이터를 URL 주소에 담아서 요청을 하게 됩니다.

이 때는 캐싱이 가능하고 브라우저 기록이 남기때문에 속도가 post 요청보다 빠릅니다.

보통은 검색하거나 페이지 이동할 때는 Get 요청을 해도 보안상 문제가 없습니다.

  • 검색할 때 사용자 아이디나 비밀번호 데이터를 넘길건 아니잖아요?ㅎㅎ
  • 상세 페이지를 볼 때도 마찬가지입니다. 키 값을 아이디나 비밀번호를 넘기면 안됩니다.

https://okky.kr/article/308149 -> 여기 한번 보시는걸 추천드립니다.

Post 요청

반면에 Post 요청을 할 경우에는 어떻게 될까요?

데이터를 메시지 바디에 담아서 보내게 됩니다.

그렇기 때문에 post 방식은 보안성은 좋지만 브라우저 기록, 캐싱 이 남지 않기 때문에 속도가 get 방식보다 떨어집니다.

자, 이제 생각해보자.

검색이나 페이지 이동은 어떤 요청을 해야할까요?

Get 방식으로 요청해야 속도가 빨라져 화면이 빠르게 렌더링될 것입니다.

애초에 검색이나 페이지 이동할 때 보안 이슈에 해당하는 중요한 데이터가 필요가 없습니다.

만약 필요가 있다면 그것은 설계를 다시 한번 고려해보는 것도 좋을 것입니다.

post 방식을 쓰면 안될까?

써도 됩니다. 하지만 주의할 점이 있습니다.

사실 이 글의 포인트인데 post 방식으로 요청하면 위와 같은 팝업창이 뜨거나 대참사를 일으킬 수 있다.

대참사의 예시를 들어보겠습니다.

post_test_1

여기 간단히 멤버의 리스트를 보여주는 페이지가 있다고 합니다.


post_test_2

위 페이지는 usernameage 데이터를 저장하는 페이지입니다.
(Form에 action="/member/member-save"과 method = "post"로 submit() 전송을 합니다.)

그리고 redirect를 시키지 않고 저장을 누르고 계속 새로고침을 누르면 어떻게 될까요?
멤버 리스트 페이지로 가서 어떻게 되었는지 확인해봅니다.


post_test_3

나도 모르게 데이터가 여러개 저장되는 것을 확인할 수 있습니다.

왜 이런 현상이 일어날까요?

  • post 전송을 하고 redirect 되지 않으면 url 주소는 그대로 남게 됩니다.
  • 여기서 새로고침을 하게 되면 그 url 주소로 계속 실행이 되서 저런 현상이 발생하게 됩니다.

중요한 정보를 보내야 할 때

먼저 post 방식은 민감한 정보를 서버에 요청해야 할 때 쓰면 좋습니다. ex) 회원정보, 로그인 등등..

그리고 나서 중요한 것이 있습니다.

바로 PRG(Post Redirect Get) 입니다.

post 방식으로 데이터를 보내면 반드시 redirect 시켜야 합니다. (302 상태코드)

그래서 post 요청은 반드시 redirect 시켜야한다는 것만 기억해주시면 됩니다.

해결 방법

  • javascript로 redirect
    • window.location.href = '/'
  • <form action="/members" method="get">
    • methodget으로
    • method="get"은 생략 가능

결론!

  • 결론은 검색이나 페이지 이동 같은 조회는 Get 요청을 적극 사용하자!
  • 반대로 위와 같은 조회를 Post 요청을 할 경우에는 조금 위험할 수 있으니 될수록 자제하자!
  • 팝업창 해결방법은 Post 요청 → Get 요청으로 변경해주거나 Post 요청을 redirect 시키면 해결!

References

댓글