1. 아래 내용의 스크립트를 추가한다.

첫번째줄은 브라우저가 ie 일때만 사용자 정의 Worker 를 사용하려고 넣었다.

if(window.navigator.userAgent.toLowerCase().indexOf('trident') > -1 || window.navigator.userAgent.toLowerCase().indexOf('MSIE') > -1)
{
	var Worker = function ( scriptFile )
	{
		console.log('익스플로어 워커다');
		var self = this ;
		var __timer = null ;
		var __text = null ;
		var __fileContent = null ;
		var onmessage ;
	
		self.onerror = null ;
		self.onmessage = null ;

		// child has run itself and called for it's parent to be notified
		var postMessage = function( text )
		{
			if ( "function" == typeof self.onmessage )
			{
				return self.onmessage( { "data" : text } ) ;
			}
			return false ;
		} ;

		// Method that starts the threading
		self.postMessage = function( text )
		{
			__text = text ;
			__iterate() ;
			return true ;
		} ;

		var __iterate = function()
		{
			// Execute on a timer so we dont block (well as good as we can get in a single thread)
			__timer = setTimeout(__onIterate,1);
			return true ;
		} ;

		var __onIterate = function()
		{
			try
			{
				if ( "function" == typeof onmessage )
				{
					onmessage({ "data" : __text });
				}
				return true ;
			}
			catch( ex )
			{
				if ( "function" == typeof self.onerror )
				{
					return self.onerror( ex ) ;
				}
			}
			return false ;
		} ;


		self.terminate = function ()
		{
			clearTimeout( __timer ) ;
			return true ;
		} ;


		/* HTTP Request*/
		var getHTTPObject = function () 
		{
			var xmlhttp;
			try 
			{
				xmlhttp = new XMLHttpRequest();
			}
			catch (e) 
			{
				try 
				{
					xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
				}
				catch (e) 
				{
					xmlhttp = false;
				}
			}
			return xmlhttp;
		}

		var http = getHTTPObject()
		http.open("GET", scriptFile, false)
		http.send(null);

		if (http.readyState == 4) 
		{
			var strResponse = http.responseText;
			//var strResponse = http.responseXML;
			switch (http.status) 
			{
				case 404: // Page-not-found error
					alert('Error: Not Found. The requested function could not be found.');
					break;
				case 500: // Display results in a full window for server-side errors
					alert(strResponse);
					break;
				default:
					__fileContent = strResponse ;
					// IE functions will become delagates of the instance of Worker
					eval( __fileContent ) ;
					/*
					at this point we now have:
					a delagate "onmessage(event)"
					*/
					break;
			}
		}

		self.importScripts = function(src)
		{
			// hack time, this will import the script but not wait for it to load...
			var script = document.createElement("SCRIPT") ;
			script.src = src ;
			script.setAttribute( "type", "text/javascript" ) ;
			document.getElementsByTagName("HEAD")[0].appendChild(script)
			return true ;
		} ;

		return true ;
	} ;
}

 

2. jsp 나 html 파일에서 스크립트를 포함시켜준다.

<script type="text/javascript" src="/ie_worker.js"></script>

 

3. 이제 사용하던 worker 를 그대로 사용해준다.

worker = new Worker("my_worker.js");   //위의 worker 파일 아님
var sessionTimeout = $("#sessionTimeOut").val();
worker.postMessage(sessionTimeout);
			 
worker.onerror = function(e) {        
	//로직
}   

worker.onmessage = function(e) {  
	//로직
}

자바의 세션 타임을 가지고, 해당 시간이 지나면 만료가 되는 타이머를 만들어 보자.

 

우선 jsp 에서 해당 소스로 세션타임아웃을 가져온다.

 

 

1
2
<input type="hidden" id="sessionTimeOut" name="sessionTimeOut" value=<%=session.getMaxInactiveInterval() %>>
 
 
 

 

해당 시간은 java -> web.xml 에서 다음과 같이 설정할 수 있다.

 

1
2
3
<session-config>
    <session-timeout>180</session-timeout>
</session-config>
 

 

이렇게 하면, 180분 후에 세션이 끊기게 되고 jsp 소스의 sessionTimeOut 에는 180 이 저장된다.

 

아래는 03:00:00 부터 1초씩 감소하여 00:00:00가 되면 로그아웃 팝업이 뜨는 소스.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
var timer;
$(document).ready(function(){
    
    doTimer($("#sessionTimeOut").val());
    $(document).on('click'"i[id='sessionRefresh']"function(){
        clearTimeout(timer);
        doTimer($("#sessionTimeOut").val());
    });
});
 
function sessionTimeOut() {
      return new Promise(function(resolve, reject) {
        $.get('/sessionTimeOutLogOut.do'function(response) {
          if (response) {
              console.log("time2");
            resolve(response);
          }
          reject(new Error("Request is failed"));
        });
      });
    }
 
function doTimer(time){
    var date = new Date(null);
    if(time){
        date.setSeconds(time);
        document.getElementById("sessionTimer").innerHTML = date.toISOString().substr(11,8);
        if(time == 0){
            sessionTimeOut().then(function(data){
                clearTimeout(timer);
                alertMessage(messageType.type.E, "세션이 만료되었습니다.",
                        "다시 로그인해주세요"function(){location.href = "/logoutProcess.do";}  )
                return;
            }).catch(function(err){
                console.error(err);
            });
 
            return;
            
        }
 
        --time;
        timer = setTimeout(doTimer, 1000, time);
    }
    return;
}
 
 
 

 

document 가 로드 되고 doTimer 를 호출 (파라미터로 세션시간을 전달)

3시간부터 시작해 1초씩 감소

 

180분이라는 파라미터를 전달받아 해당 시간을 03:00:00 (3시간) 으로 변환해서 화면에 뿌려준다.

 

27번째 줄 : 화면에 남은 시간을 표시

42번째 줄 : time 을 1초씩 감소

43번째 줄 : 1초마다 doTimer 를 호출, (재귀함수처럼 사용)

 

 

재귀함수처럼 사용 한 이유는, setInterval 로 사용 시 03:00:00 로 시작은 하되 타이머가 한발 늦게 시작한다.

1초후 02:59:59 로 바로 표시해주기 위해 setInterval 이 아닌 setTimeout 을 재귀함수처럼 사용했다.

 

 

5번째 줄 : 세션 연장 아이콘 클릭 시, 3시간 부터 다시 세션 타임 아웃 시작!

6번째 줄 : clearTimeout(타이머) 를 하지 않으면, 먼저 실행됐던 3시간의 타이머와 현시각부로 다시 호출할 타이머가 화면에 동시에 나타나므로 (이전 세션 시간이 1시간이 남았을 경우 화면에는 01:00:00 , 00:59:59.. 와 03:00:00, 02:59:59 가 번갈아서 표시된다.) 꼭 초기화를 해준 후 다음 타이머를 호출 해 준다.

 

 

28번째 줄 : 남은 시간이 0초가 되었을 경우, 세션을 제거하는 컨트롤러를 먼저 호출 후, 세션이 제거 되었으면 세션이 만료되었다는 메세지를 화면에 표시한다.

만료되었다는 메세지를 사용자가 클릭하면 로그인 페이지로 이동한다.

 

 

 

위의 소스는 해당 브라우저의 탭에서만 머물 경우는 문제가 없으나, 다른 탭을 띄워놓을 경우 크롬, 엣지 등 브라우저 정책으로 인해 타이머가 제대로 동작하지 않을 수 있다. 이는 worker 기능을 사용하여 개선할 수 있다. (다음에 작성...)

ajax 로 데이터를 불러오다보면 for 문으로 데이터를 뿌려줄 때가 많은데,

<td id="tdid1"> <td id="tdid2"> ... 이런식으로 데이터를 뿌려줄 때가 있다.

 

그렇다면 td 에 대한 id 가 tdid 로 시작하는 노드 모드를 가져 오고 싶을 때는 아래와 같이 쓰면 된다.

1
var nodes= $("td[id*='tdid']");
 

 

이렇게 하면 nodes 에는 html 태그가 td 이고 id 가 tdid 로 시작하는 td들을 모두 담을 수 있다.

 

노드들의 갯수 : nodes.length;

text 가져오기 : node[i].innerHTML;

text 변경하기 : node[i].outerHTML = "변경할값";

 

예시)

 

1
2
3
4
5
6
7
8
var node = $("span[id*='phone']");
if (node.length != 0) {
        for (var i = 0; i < node.length; i++) {
            var phone = node[i].innerHTML;
            phone = telNoBeautify(phone);
            node[i].outerHTML = phone;
        }
    }
 
 

 

1
2
3
4
5
6
7
8
$("#chkAll").click(function(){
    if($("#chkAll").is(":checked")){
        $("input[name='chkUser']").prop("checked"true);
        }
        else{
        $("input[name='chkUser']").prop("checked"false);
        }
    });
 
cs

chkAll -> 헤더에 있는 체크박스 아이디

 

input type="checkbox" 이고 name ="chkUser" 인 체크박스들을 제어

+ Recent posts