Jsp 뒤로가기 막기 - jsp dwilogagi maggi

자바스크립트(Javascript) 뒤로 가기 막는 방법

보통 다음 페이지로 이동할 때 location.href URL 을 넣어서 이동을 시키게 됩니다. 그럼 뒤로 가기가 가능해 집니다. 브라우저에 뒤로 가기 버튼이 활성화 되죠. 이렇게 뒤로 가기가 되지 않도록 페이지 이동을 시킬 수가 있습니다.

어떤 웹 사이트에서는 보안상의 이유로 뒤로 가기가 안되도록 구현하는 곳이 있습니다. 먼저 뒤로 가기가 되는 일반적인 경우를 보겠습니다. 페이지 이동을 위해 버튼을 클릭했을 때 move 함수를 실행하도록 만들었습니다. 페이지 이동은 location.href 를 변수를 사용합니다.

<!DOCTYPE HTML>
<html>
<head>
<meta content="text/html; charset=euc-kr">
<title>페이지 이동 </title>
</head>
<script type="text/javascript">
	function move(){
		location.href="history02.html";
	}
</script>
<body>
첫 번째 페이지 입니다.<br/><br/>
<input type="button" value="다음 >" onClick="javascript:move();">
</body>
</html>

위의 소스를 실행했을 때 이동한 history02.html 페이지에서 웹 브라우저 뒤로 가기 버튼이 활성화 되어 있는 것을 알 수 있습니다. 그러니까 이동이 가능하다는 것이죠.

Jsp 뒤로가기 막기 - jsp dwilogagi maggi

브라우저에 뒤로 가기 버튼을 비활성화 시키려면 이전 이력이 남지 않는 replace 함수를 사용해야 합니다. location 객체의 replace() 함수 파라미터로 이동할 주소를 넣으시면 됩니다.


<!DOCTYPE HTML>
<html>
<head>
<meta content="text/html; charset=euc-kr">
<title>페이지 이동 </title>
</head>
<script type="text/javascript">
	function move(){
		location.replace("history02.html");
	}
</script>
<body>
첫 번째 페이지 입니다.<br/><br/>
<input type="button" value="다음 >" onClick="javascript:move();">
</body>
</html>

아래 그림처럼 location.replace() 함수를 이용해서 다음 페이지로 이동시키면 상단에 있는 브라우저 이전 버튼은 활성화가 되어 있지 않습니다 

 개요

브라우저에서 뒤로가기를 누를 경우 IE는 "웹페이지가 만료되었습니다." 크롬은 "양식 다시 제출 확인" 이라는 오류 메시지를 볼 수 있습니다.  해당 증상은 웹페이지 요청시 POST로 전송된 데이터가 있는 페이지를 다시 요청했을경우 나타나며 주로 뒤로가기를 했을때 많이 볼수 있는데 사용자 입장에서는 시스템 오류로 느껴질 수 있습니다. 

위 증상의 해결을 위해서 가장 간단한 해결방법은 GET방식으로 데이터를 주고 받는 것입니다. 

아니면 AJAX, HASH, history API 등을 활용하여 설계 단계부터 SPA(single page application) 형태로 서비스를 구성하면 위 이슈없이 깔끔한 서비스 구성이 가능 하겠죠!

하지만 레거시 시스템 유지보수중 리스크 없이 위 내용을 쉽게 적용할 수 있는 경우가 많지 않을거라 생각됩니다. 

남은 방법은 "뒤로가기"에 해당하는 어떤한 이벤트를 캐치하여 페이지 이동을 막거나 정상적으로 이전 페이지에 데이터를 전송하도록 스크립트로 제어하는 방법인데 안타깝게도 브라우저 엔진 안에서 구동되는 웹프로그램의 구조상의 한계 때문에 웹프로그램내 스크립트를 통해 100% 제어할 수 있는 방법은 없습니다.

그래도 이번 포스팅에서 제한적으로나마 History API  pushState 와  popstate  이벤트를 이용하여 뒤로가기 버튼 이벤트를 핸들링할 수 있는 방법을 소개합니다. 

( backbutton event handling )

 History control ( popstate / pushState )

페이지 진입시 먼저 history.pushState 인터페이스를 통해 새로운 history state를 추가 하여 바로 이전 페이지로 갈 수 없도록 만들어 줍니다.

history.pushState(state, title, url);
//state : 새 history 항목과 관련된 JavaScript 객체입니다  직렬화 할 수있는 모든 것으로 해당값을 표현 가능합니다.
//title : 새 history 항목의 title 입니다.
//url : 새 history 항목의 URL 입니다.

이후 페이지가 뒤로가면서 생기는 history의 변경을 popstate 이벤트로 캐치 하여 처리 하는 방식입니다.

history가 변경되는 시점에 window 내에서 핸들링 된 히스토리 변경이 아닌 외부(뒤로가기 버튼 등)에 의한 변경인지 판단하는 기준window 영역에 mouse가 있지 여부로 판단합니다. ( mouseout / mouserover )

이벤트를 캐치했으면 이전 POST 페이지로 정상적으로 갈수 있도록 스크립트를 통해 데이터를 SUBMIT하거나 혹은 history를 조작하여 이전 페이지로의 이동을 막아주시면 됩니다

 Example

var backControl = function(callbackFunction) {
      //window 내 mouse 위치 여부를 체크하기 위한 변수 
      window.innerDoc = false; 		
      //mouseover Event Listener 
      window.addEventListener('mouseover', function(event) {    
          window.innerDoc = true;
      }); 
      // mouseout Event Listener 
      window.addEventListener('mouseout', function(event) {                
          window.innerDoc = false;
      });
      // 바로 이전 페이지로 이동하는 것을 막기위해 history State 추가 
      history.pushState({page:"first"},  document.title, location.pathname + '#first');
      
      //popstate Event Listener 
      window.addEventListener('popstate', function(event) { 
	  // history State 추가하여 페이지 이동 막음 (뒤로가기 막기)
	  history.pushState({page:"historyChanged"},  document.title, location.pathname + '#changed');	
	
	  // window 영역 밖에서 history가 변경 됐을경우 callbackFunction 실행 ( 뒤로가기 버튼 등 )  
// 이전 POST 페이지에 정상적으로 데이터 재전송하여 SUBMIT 등 수행 if (!window.innerDoc) { callbackFunction();
} }); }

// window 영역 밖의 핸들링 되지 않은 버튼으로 history 변경 이동했을 경우 실행할 Function
var callbackFunction = function() {
	// document.referrer 등 체크하여 이전 POST 페이지로 정상 이동 할 수 있도록 데이터 생성 및 추가 및 submit
	// window 내 버튼 등을 통한 이동 외에 페이지 이동 불가 alret 안내 등 처리 
}
//스크립트 실행
backControl(callbackFunction);

 제약사항

처리방식을 보면 아시겠지만 사실 이 방법은 완벽하지 않은 방법입니다.

단순 뒤로가기 막기는 PC, MOBILE 환경에 관계없이 적용이 가능하나 

window.innerDoc 값 체크를 통하여 뒤로가기 버튼 판단 후 함수 실행하는 로직은  페이지내에서 스와이프같은 인터액션으로 이동했거나 모바일 브라우저 일경우는 history 변경시 mouse 위치를 통해 뒤로가기라는 여부를 판단할 수 없기 때문에 PC 환경에서만 제한적으로 적용이 가능합니다.

모바일환경의 대부분의 브라우저는 뒤로가기를 통해 POST로 재전송할 경우 바로 만료페이지가 뜨지않고 데이터 재전송 여부를 묻기 때문에 이전 페이지 진입 후 웹페이지 만료에대한 이슈는 적은 편이긴 합니다.

그리고 브라우저마다 이벤트 동작하는 것이 조금씩 다르기 때문에 생기는 제약사항들도 있습니다.  예를 들어 크롬 브라우저같은 경우 WINDOW내 아무 액션 없이 바로 뒤로가기를 누를 경우 popstate 이벤트를 포함한 아무런 이벤트도 발생하지 않습니다.  아마 보안상의 이유인듯 싶네요.

위에 기재 드린 것 처럼 웹프로그램내 스크립트로 브라우저 엔진내에서 동작하는 웹프로그램 동작을 완벽하게 컨트롤하는 것은 불가능하니 이런 내용은 원천적으로 설계 단계부터 잘 고려하여 적용 하실 일이 없도록 하는게 가장 좋은 일이겠습니다. :)  

tag ajax, backbutton, chorme, hash, history API, popstate, POST 뒤로가기, pushState, single page application, Spa, 뒤로가기 막기, 뒤로가기 버튼, 뒤로가기 양식 다시 제출, 뒤로가기 웹페이지가 만료되었습니다., 뒤로가기 이벤트, 브라우저, 양식 다시 제출 확인, 웹페이지가 만료되었습니다., 크롬