Last Modified : 2009.09.19
Ajax - First Steps
간단한 예로서 Ajax 가 기존의 웹 프로그램 기법과 어떤 차이가 있는지 살펴보겠습니다. 예제는 회원등록 화면에서 아이디 중복 체크를 하는 것입니다. 먼저 팝업창을 이용하는 방법입니다.
1. 팝업창을 이용한 ID 중복 체크
write_form.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>회원가입양식</title>
<script type="text/javascript">
function checkID() {
var form = document.getElementById("signform");
var id = form.id.value;
if (id != '' ) {
var winFeatures = "toolbar=no," +
"location=no," +
"directories=no," +
"status=no," +
"menubar=no," +
"scrollbars=no,"+
"resizable=no,"+
"copyhistory=no,"+
"width=400, height=400";
window.open("popIDCheck.jsp?id="+id, "IDCheckWin", winFeatures);
} else {
alert('ID를 입력하세요!');
}
}
</script>
</head>
<body>
<form id="signform" action="write.jsp" method="post">
<p>
ID <input type="text" name="id" />
<input type="button" value="ID중복체크" onclick="checkID()" />
</p>
<p>
<span id="idChkMsg"></span>
</p>
</form>
</body>
</html>
popIDCheck.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ page import="java.sql.*" %>
<%
String id = request.getParameter("id");
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "select count(*) from member where id = ?";
boolean isExist = false;
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
try {
con = DriverManager.getConnection(url,"scott","tiger");
pstmt = con.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
if ( rs.next() ) {
int i = rs.getInt(1);
if ( i > 0 ) isExist = true;
}
} catch ( SQLException e ) {
System.out.println( "Error Source:popIDCheck.jsp : SQLException" );
System.out.println( "SQLState : " + e.getSQLState() );
System.out.println( "Message : " + e.getMessage() );
System.out.println( "Oracle Error Code : " + e.getErrorCode() );
System.out.println( "Query : " + sql );
} finally {
rs.close();
pstmt.close();
con.close();
}
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>ID 중복 체크</title>
<script type="text/javascript">
function idCheck() {
var form = document.getElementById("frmID");
if ( form.id.value == '' ) {
alert('ID를 입력하세요!');
return;
}
form.submit();
}
function idConfirm(id) {
var form = opener.document.getElementById("signform");
form.id.value = id;
self.close();
}
</script>
</head>
<body>
<%
if ( isExist == true ) {
%>
<p>
<%=id %>는 이미 사용중입니다.<br />
다른 ID를 사용하세요!
</p>
<form id="frmID" action="popIDCheck.jsp" method="post">
<p>
ID <input type="text" name="id" />
<input type="button" value="ID중복체크" onclick="idCheck()" />
</p>
</form>
<%
} else {
%>
<%=id %>는 사용할 있습니다.<br />
<input type="button" value="확인" onclick="idConfirm('<%=id %>')" />
<%
}
%>
</body>
</html>
브라우저 설정에 따라 팝업창을 띄우지 않도록 할 수 있기 때문에 이제는 좋은 방법이 되지 못합니다. 다음은 iframe 을 이용하여 ID 중복 체크입니다.
2. iframe 을 이용한 ID 중복 체크
write_form.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>회원가입양식</title>
<script type="text/javascript">
function checkID() {
var checkform = document.getElementById("checkform");
var signform = document.getElementById("signform");
var id = signform.id.value;
if ( id != '' ) {
checkform.id.value = id;
checkform.submit();
} else {
alert('ID를 입력하고 중복확인하세요!')
signform.id.value = '';
signform.id.focus();
}
}
var textNode;
function idNotOKMsg ( id ) {
var msg = document.getElementById('idChkMsg');
if ( textNode ) msg.removeChild(textNode);
var str = id + " 는 이미 사용자가 있습니다. 다른 ID를 사용하세요.";
textNode = document.createTextNode(str);
msg.appendChild(textNode);
msg.style.background = "#FCBFC0";
}
function idOKMsg ( id ) {
var msg = document.getElementById('idChkMsg');
if ( textNode ) msg.removeChild(textNode);
var str = id + " 는 사용이 가능한 ID입니다.";
textNode = document.createTextNode(str);
msg.appendChild(textNode);
msg.style.background = "#BFCDFC";
}
</script>
</head>
<body>
<form id="signform" action="write.jsp" method="post">
<p>
ID <input type="text" name="id" />
<input type="button" value="ID중복체크" onclick="checkID()" />
</p>
<p>
<span id="idChkMsg"></span>
</p>
</form>
<form id="checkform" action="iframeIDCheck.jsp" method="post" target="iIDCHKframe">
<input type="hidden" name="id" />
</form>
<iframe id="iIDCHKframe" name="iIDCHKframe"
style="width: 0px;height: 0px;border: 0px;"></iframe>
</body>
</html>
iframeIDCheck.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ page import="java.sql.*" %>
<%
String id = request.getParameter("id");
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String sql = "select count(*) from member where id = ?";
boolean isExist = false;
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
try {
con = DriverManager.getConnection(url,"scott","tiger");
pstmt = con.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
if ( rs.next() ) {
int i = rs.getInt(1);
if ( i > 0 ) isExist = true;
}
} catch ( SQLException e ) {
System.out.println( "Error Source:iframeIDCheck.jsp : SQLException" );
System.out.println( "SQLState : " + e.getSQLState() );
System.out.println( "Message : " + e.getMessage() );
System.out.println( "Oracle Error Code : " + e.getErrorCode() );
System.out.println( "Query : " + sql );
} finally {
rs.close();
pstmt.close();
con.close();
}
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>ID 중복 체크</title>
</head>
<body>
<%
if ( isExist == true ) {
%>
<script type="text/javascript">
parent.idNotOKMsg( '<%=id %>' );
</script>
<%
} else {
%>
<script type="text/javascript">
parent.idOKMsg( '<%=id %>' );
</script>
<%
}
%>
</body>
</html>
앞으로의 웹은 아마도 팝업창을 이용하거나 ifrmae 을 이용하는 이와 같은 방식은 점점 좋은 방법이 되지 못할 것입니다. xhtml 1.0 strict 에서는 팝업창과 iframe 을 아예 사용할 수 없기 때문입니다.
3. Ajax 를 이용한 ID 중복 체크
write_form.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=EUC-KR">
<title>회원가입양식</title>
<script type="text/javascript">
var xmlHttp = false;
try {
xmlHttp = new XMLHttpRequest();
} catch ( trymicrosoft ) {
try {
xmlHttp = new ActiveXObject( "Msxml2.XMLHTTP" );
} catch ( othermicrosoft ) {
try {
xmlHttp = new ActiveXObject( "Microsoft.XMLHTTP" );
} catch ( failed ) {
xmlHttp = false;
}
}
}
if ( !xmlHttp ) {
alert( "Error initializing XMLHttpRequest!" );
}
function checkID() {
var form = document.getElementById("signform");
var id = form.id.value;
// TODO 아이디 유효성 체크
var queryString = "id=" + id;
var url = "ajaxIdCheck.jsp";
xmlHttp.open("POST", url, true);
xmlHttp.onreadystatechange = updatePage;
xmlHttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttp.send(queryString);
}
function updatePage() {
if ( xmlHttp.readyState == 4 ) {
showIDCheckMsg();
}
}
function showIDCheckMsg() {
var response = xmlHttp.responseText;
var str = response.split("|");
var msg = document.getElementById( "idChkMsg" );
if ( str[0] == 0 ) {
idOKMsg ( str[1] );
} else {
idNotOKMsg ( str[1] );
}
}
var textNode;
function idNotOKMsg ( id ) {
var msg = document.getElementById('idChkMsg');
if ( textNode ) msg.removeChild(textNode);
var str = id + " 는 이미 사용자가 있습니다. 다른 ID를 사용하세요.";
textNode = document.createTextNode(str);
msg.appendChild(textNode);
msg.style.background = "#FCBFC0";
}
function idOKMsg ( id ) {
var msg = document.getElementById('idChkMsg');
if ( textNode ) msg.removeChild(textNode);
var str = id + " 는 사용이 가능한 ID입니다.";
textNode = document.createTextNode(str);
msg.appendChild(textNode);
msg.style.background = "#BFCDFC";
}
</script>
</head>
<body>
<form id="signform" action="write.jsp" method="post">
<p>
ID <input type="text" name="id" />
<input type="button" value="ID중복체크" onclick="checkID()" />
</p>
<p>
<span id="idChkMsg"></span>
</p>
</form>
</body>
</html>
ajaxIdCheck.jsp
<%@ page language="java" contentType="text/html; charset=EUC-KR"
pageEncoding="EUC-KR"%>
<%@ page import="java.sql.*" %>
<%
String id = request.getParameter("id");
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection con = null;
String sql = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
int result = 0;
String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
try {
con = DriverManager.getConnection(url,"scott","tiger");
sql = "select count(*) from member where id = ?";
pstmt = con.prepareStatement(sql);
pstmt.setString(1, id);
rs = pstmt.executeQuery();
rs.next();
result = rs.getInt(1);
} catch ( SQLException e ) {
System.out.println( "Error Source:ajaxIdCheck.jsp : SQLException" );
System.out.println( "SQLState : " + e.getSQLState() );
System.out.println( "Message : " + e.getMessage() );
System.out.println( "Oracle Error Code : " + e.getErrorCode() );
System.out.println( "Query : " + sql );
} finally {
rs.close();
pstmt.close();
con.close();
}
out.println ( result + "|" + id);
%>
기존 기술과 차이점은 자바스크립트를 이용하여 서버 컴포넌트와 직접 통신한다는 것입니다.
참고 문서
http://www.w3schools.com/HTMLDOM/met_win_open.asp
http://www.ibm.com/developerworks/kr/series/web/index.html
