지난 시간 Form onsubmit 이벤트 시 isSubmit 플래그를 이용하여 submit을 제어하는 방법을 언급하였습니다.
결론부터 얘기를 하면 ajax 통신이 성공이었을 때, 추가 작업을 진행하지 못하고 submit이 되는 버그를 발견하였습니다.
ajax 통신이 error가 났을 때는 원하는 대로 제어가 가능하였는데, 성공 시에는 제어가 되지 않습니다.
해결 방법으로는 Form 태그의 onsubmit을 사용하지 않고 jquery의 $('#theForm').submit(function(event){})을
이용하여 해결이 가능합니다.
중요한 것은 event.preventDefault(); 를 선언하여 submit 이벤트를 무력화 시킨 후
javascript에서 원하는 작업을 모두 마친 후 this.submit(); 을 통해서 Form 전송을 시킬 수 있습니다.
Javascript jquery submit 이벤트 시 자동 submit 보내지 않기
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form name="theForm" action="" method="post" id="theForm">
<input type="submit" />
</form>
<script>
$('#theForm').submit(function(event){
// 자동 submit을 시키는 것을 막는다.
event.preventDefault();
/**
* 입력 필드 validattion check 로직
*/
/**
* ajax로 다른 페이지를 처리 후에 결과가 성공일 때 전송 처리를 한다.
*/
// 전송 여부 boolean 값
// 초기값은 false로 셋팅을 한다.
var isSubmit = false;
$.ajax({
url:'[주소]',
type:'post',
data:$('form').serialize(),
dataType:'json',
// 다른 페이지를 처리 후에 결과가 성공일 때
// 비동기식으로 처리를 함
async: false,
success:function(data)
{
var message = data.message;
// 결과값이 성공이면 전송 여부는 true
if ( message == 'Success' )
{
isSubmit = true;
}
else
{
// 결과값이 실패이면 전송 여부는 false
// 앞서 초기값을 false로 해 놓았지만 한번 더 선언을 한다.
isSubmit = false;
}
},
error:function(request, status, error)
{ // 오류가 발생했을 때 호출된다.
console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
// ajax 처리가 결과가 에러이면 전송 여부는 false
// 앞서 초기값을 false로 해 놓았지만 한번 더 선언을 한다.
isSubmit = false;
},
beforeSend:function()
{
// 로딩바를 보여준다.
},
complete:function()
{
// 로딩바를 해제한다.
}
});
if ( isSubmit ) this.submit();
})
</script>
</body>
</html>
Form에서 onsubmit 이벤트를 사용할 때 Javascript로 ajax 결과에 따라서 전송 처리하는 방법입니다.
1. ajax 설정 값 중 async를 false로 설정합니다.
- async: false 는 동기식 즉 절차적으로 처리를 한다는 의미입니다. - async: false 를 하지 않으면 전송 결과에 상관없이 submit이 되어 버립니다.
2. ajax 처리 결과에서는 전송 여부 설정을 하고 이 값을 이용하여 return false 처리를 합니다.
- 전송 결과에서 return false 처리를 하여도 전송 처리가 됩니다.
<<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form name="theForm" method="post" onsubmit="return thisFormSubmit(this);">
<input type="submit" />
</form>
<script>
function thisFormSubmit(f) {
/**
* 입력 필드 validattion check 로직
*/
/**
* ajax로 다른 페이지를 처리 후에 결과가 성공일 때 전송 처리를 한다.
*/
// 전송 여부 boolean 값
// 초기값은 false로 셋팅을 한다.
var isSubmit = false;
$.ajax({
url:'[주소]',
type:'post',
data:$('form').serialize(),
dataType:'json',
// 다른 페이지를 처리 후에 결과가 성공일 때
// 비동기식으로 처리를 함
async: false,
success:function(data)
{
var message = data.message;
// 결과값이 성공이면 전송 여부는 true
if ( message == 'Success' )
{
isSubmit = true;
}
else
{
// 결과값이 실패이면 전송 여부는 false
// 앞서 초기값을 false로 해 놓았지만 한번 더 선언을 한다.
isSubmit = false;
}
},
error:function(request, status, error)
{ // 오류가 발생했을 때 호출된다.
console.log("code:"+request.status+"\n"+"message:"+request.responseText+"\n"+"error:"+error);
// ajax 처리가 결과가 에러이면 전송 여부는 false
// 앞서 초기값을 false로 해 놓았지만 한번 더 선언을 한다.
isSubmit = false;
},
beforeSend:function()
{
// 로딩바를 보여준다.
},
complete:function()
{
// 로딩바를 해제한다.
}
});
if ( !isSubmit ) return false;
}
</script>
</body>
</html>
Javascript Form onsubmit 이벤트 시 ajax 결과에 따라서 전송 처리하기 - async: false
PHP가 아닌 클라이언트인 브라우저에서 Javascript로 주민등록번호 유휴성 검사를 하는 로직입니다.
외국인의 경우 별도 로직을 구성하여야 해서 내국인만 정리하였습니다.
function isKorJumin(ssn1, ssn2)
{
var n = 2;
var sum = 0;
for (var i = 0; i < ssn1.length; i++)
{
sum += parseInt(ssn1.substr(i, 1)) * n++;
}
for (var i = 0; i < ssn2.length - 1; i++)
{
sum += parseInt(ssn2.substr(i, 1)) * n++;
if (n == 10)
{
n = 2;
}
}
var checkSum = 11 - sum % 11;
if (checkSum == 11)
{
checkSum = 1;
}
if (checkSum == 10)
{
checkSum = 0;
}
if (checkSum != parseInt(ssn2.substr(6, 1)))
{
return false;
}
return true;
}
var ssn1 = '710606';
var ssn2 = '2240475';
console.log( isKorJumin(ssn1, ssn2) );
// result
// true
브라우저에서 자바스크립트의 setTimeout을 이용하여 타이머 셋팅을 한 후 원하는 시간이 되면 타이머를 초기화 하고 ajax로 세션 유지 처리를 하는 프로그램를 호출하면 됩니다.
var timeoutHnd = null;
var logouTimeInterval = 3 * 60 * 1000; // 3 mins here u can increase session time
function OnTimeoutReached() {
$.ajax({
url:'세션 유지를 위한 처리 주소'
});
ResetLogOutTimer();
}
function ResetLogOutTimer() {
clearTimeout(timeoutHnd);
// set new timer
timeoutHnd = setTimeout('OnTimeoutReached();', logouTimeInterval);
}
timeoutHnd = setTimeout('OnTimeoutReached();', logouTimeInterval);
Javascript ajax setTimeout를 이용하여 3분 간격 세션 자동 연장 처리
beforeunload 이벤트의 경우 window.addEventListener를 통해서 처리를 할 때 잘 되었습니다.
단순히 beforeunload만을 사용할 경우 페이지 내에서 새로고침, 링크 연결 등 다양한 액션에도 동작을 하게 되어 원하는 결과를 얻을 수 없습니다.
그래서 각각의 이벤트를 확인하여 진행이 되지 않도록 처리를 한 후 브라우저가 꺼졌을 경우에만 처리가 되도록 합니다.
ajax 사용시 async 를 false로 처리를 하여 비동기 통신이 아닌 동기 통신으로 변경을 하여야 처리가 됩니다.
var closing_window = false;
$(window).on('focus', function () {
closing_window = false;
//if the user interacts with the window, then the window is not being
//closed
});
$(window).on('blur', function () {
closing_window = true;
if (!document.hidden) { //when the window is being minimized
closing_window = false;
}
$(window).on('resize', function (e) { //when the window is being maximized
closing_window = false;
});
$(window).off('resize'); //avoid multiple listening
});
$('html').on('mouseleave', function () {
closing_window = true;
//if the user is leaving html, we have more reasons to believe that he's
//leaving or thinking about closing the window
});
$('html').on('mouseenter', function () {
closing_window = false;
//if the user's mouse its on the page, it means you don't need to logout
//them, didn't it?
});
$(document).on('keydown', function (e) {
if (e.keyCode == 91 || e.keyCode == 18) {
closing_window = false; //shortcuts for ALT+TAB and Window key
}
if (e.keyCode == 116 || (e.ctrlKey && e.keyCode == 82)) {
closing_window = false; //shortcuts for F5 and CTRL+F5 and CTRL+R
}
});
// Prevent logout when clicking in a hiperlink
$(document).on("click", "a", function () {
closing_window = false;
});
// Prevent logout when clicking in a button (if these buttons rediret to some page)
$(document).on("click", "button", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("submit", "form", function () {
closing_window = false;
});
// Prevent logout when submiting
$(document).on("click", "input[type=submit]", function () {
closing_window = false;
});
var toDoWhenClosing = function() {
$.ajax({
type: "POST",
url: "/logout.php",
async: false
});
return;
};
window.addEventListener("beforeunload", function (e) {
if (closing_window) {
toDoWhenClosing();
}
});