Ajax 기술 문서(작성자 : 김연수)
(첫 회사에 입사하여 만든 사내 배포용 기술 문서)
Ajax In Action 도서를 참고하며 자료를 만들었으며, 이 자료를 만들면서 AJAX에 대한 많은 이해를 하게 됐던 거 같다.
작성일자는 잘못된 것이고, 2007년에 만들고 발표한 것으로 추정된다.
Contents
Ajax 처리 절차
활용사례
더블콤보박스
콤보박스 예제
콤보박스 예제 소스
XML, JSON
XML 예제
JSON 예제
Ajax POST 방식 폼 데이터 전송
Ajax 라이브러리 소개
※ 자료 참조 : 『 Ajax 인 액션』
데이브 크레인 , 에릭 파스카렐로 외 지음
에이콘 출판사
2
3.
Ajax 처리 절차
Ajax애플리케이션의 처리 절차
< 로그인 페이지 >
1. 사용자가 로그인 하면 애플리케
이션의 클라이언트에 해당하는 부
분이 브라우저로 전송
1
2. 필요할 때마다 서버에 데이터
요청
2
3
4.
활용사례
네이버 – 자동완성기능
네이버에서검색어를 입력하면 페
이지 이동 없이 아래에 자동완성
창이 표시된다 .
야후 – UI 변경
해당 메뉴에 마우스를 올리면 페
이지 이동 없이 UI 가 자동으로
변경된다 .
구글맵
마우스를 움직이면 페이지 이동없
이 동적으로 화면이 전환된다 .
4
5.
더블 콤보박스
더블 콤보박스
<클라이언트 >
사용자가 첫번째 콤보 박스를 선
택하면 , 클라이언트 자바스크립트
는 두번째 콤보박스의 내용을 채
울 정보 , 즉 첫 번째 목록에서 선
택한 콤보박스와 그에 해당하는
목록을 넣을 두 번째 콤보 박스의
이름만을 묶어 서버에게 요청을
전송한다 .
< 서버 >
서버가 요청을 받으면 데이터베이
스를 호출해 필요한 정보를 뽑아
내고 , 사용자가 선택한 지역에 속
한 목록 , 해당하는 내용을 채울
콤보 박스의 이름과 콤보 박스가
들어 있는 HTML 폼의 이름을
XML 문서의 형태로 담아 믈라이
언트에게 전송한다 .
5
6.
콤보박스 예제
onChange
( 변경시)
서버
State 박스의 Value 전 옵션 데이터 전송
송
<span class="elem" id="cities">
<select>
</select>
</span>
서버가 전송한 옵션데이터를 innerHTML 로 <span> 부분에 삽입
<option value='San Francisco'>San Francisco</option>
<option value='Los Angeles'>Los Angeles</option>
<option value='Web 2.0 City'>Web 2.0 City</option>
<option value='barcamp'>BarCamp</option>
6
콤보박스 예제 실행 화면
첫번째 콤보박스에서 onChange
이벤트가 발생하게 되면 클라이
언트 ( 브라우저 ) 는 서버와 비동기
통신을 하여 두번째 콤보박스의
값을 가져 오게 된다 . 그리고 가
져온 데이터는 innerHTML 로 뿌
려준다 .(span, div 영역 )
7.
콤보박스 예제 소스(HTML-1)
<html>
<head>
<script type="text/javascript">
콤보박스 소스 (HTML)
1. xmlHttpRequest 객체 생성
2. populateList() : 서버에 폼 데이
터 전송
3. getCities 서버에서 가져온 데이
터 ( 문자열 ) 를 span, div 영역에
innerHTML 로 삽입 .
var xmlhttp = false;
if (window.XMLHttpRequest) {
xmlhttp = new XMLHttpRequest( );
//xmlHttpRequest 객체 생성
xmlhttp.overrideMimeType('text/xml');
//MimeType 지정
} else if (window.ActiveXObject) {
// 브라우저가 xmlHttpRequest 객체 지원 하지 않을땐 액티브 X 형태로 객체를 생성
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
function populateList( ) {
// 서버에 폼 데이터를 전송하는 함수
var state = document.forms[0].elements[0].value;
var url = 'combobox.jsp?state=' + state;
xmlhttp.open('GET', url, true);
//GET 방식으로 url 전송
xmlhttp.onreadystatechange = getCities;
xmlhttp.send(null);
}
function getCities( ) {
// 서버에서 전송한 HTML 을 GET 하여 cities 라는 <span> 에 할당하는 함
수
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
// 제대로 전송 받았을때
document.getElementById('cities').innerHTML = "<select>" + xmlhttp.responseText +
"</select>";
} else {
// 전송 실패시
document.getElementById('cities').innerHTML = 'Error: preSearch Failed!';
}
}
</script>
</head>
7
콤보박스 예제 소스(JSP- 서버 컴포넌트 )
<%@page contentType="text/html;charset=euc-kr"%>
<%
request.setCharacterEncoding("euc-kr");
String state=request.getParameter("state");
데이터를 읽어온다 .
String result="";
// 클라이언트가 전송한
if(state==null) {
// 전송된 데이터가 널이면
result="No State Sent";
}else {
// 전송된 데이터가 있을때
if(state.equals("MO")){
result = "<option value='St. Louis'>St. Louis</option>" +
"<option value='Kansas City'>Kansas City</option>";
}else if(state.equals("WA")){
result = "<option value='Seattle'>Seattle</option>" +
"<option value='Spokane'>Spokane</option>" +
"<option value='Olympia'>Olympia</option>";
}else if(state.equals("CA")){
result = "<option value='San Francisco'>San Francisco</option>" +
"<option value='Los Angeles'>Los Angeles</option>"+
"<option value='Web 2.0 City'>Web 2.0 City</option>"+
"<option value='barcamp'>BarCamp</option>";
}else if(state.equals("ID")){
result = "<option value='Boise'>Boise</option>";
}else{
result="Error";
}
%>
<%=result%>
// 클라이언트에 전송할 데이터
<%
}
%>
9
콤보박스 소스 (JSP 부분 )
클라이언트 ( 브라우저 ) 로 전송할
데이터를 보내주는 파일이다 .
state 변수는 클라이언트가 전송한
콤보박스의 value 이다 .
result 변수는 클라이언트에 전송
할 데이터
(xmlhttp.responseText ) 이다 .
10.
XML, JSON 방식
(XML,JSON)
위의 방법들은 데이터가 복잡할 경우 효율적이지 못하다 . 데이터
가 복잡할 경우나 데이터를 HTML 형태로 표현하고 싶지 않은 경
우라면 , 그 대신 XML 이나 JSON 을 사용할수 있다 .
단 , XML 사용시 그만큼 부하도 커진다 .
(XML 은 유효한 XML 이어야 한다 . 즉 , root 엘리먼트가 다른 모
든 데이터를 포함해야 한다 .)
반면 , JSON 은 경량 데이터 교환 포맷이다 .
JSON(JavaScript Object Notation: 자바스크립트 객체 표기법 ) 은
서버측 구조를 자바스크립트 객체로 변경하는 포맷을 제공한다 .
이로써 데이터를 매우 쉽게 주고 받을 수 있다 .
10
11.
XML 예제 (HTML)
functiongetCities( ) {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
try {
var citynodes = xmlhttp.responseXML.getElementsByTagName('city');
for (var i = 0; i < citynodes.length; i++) {
var name = value = null;
for (var j = 0; j < citynodes[i].childNodes.length; j++) {
var elem = citynodes[i].childNodes[j].nodeName;
var nodevalue = citynodes[i].childNodes[j].firstChild.nodeValue;
if (elem == 'value') {
value = nodevalue;
} else {
name = nodevalue;
}
}
document.forms[0].elements[1].options[i] = new Option(name,value);
}
} catch (e) {
alert(e.message);
}
} else {
document.getElementById('cities').innerHTML = 'Error: No Cities';
}
}
//]]>
</script>
XML 예제 (HTML)
getCities() 는 서버에서 전송한
XML 데이터를 적절히 파싱하여
콤보박스의 옵션을 생성 하는 기
능을 한다 .
11
12.
XML 예제 (JSP)
<%@pagecontentType=" text/xml;;charset=utf-8"%>
<%
request.setCharacterEncoding("utf-8");
String state=request.getParameter("state");
어온다
String result=“”;
// 클라이언트가 전송한 데이터를 읽
if(state=null) {
echo "<city>No State Sent</city>";
} else {
if(state.equals(“MO”)){
result = "<city><value>stlou</value><title>St. Louis</title></city>" .
"<city><value>kc</value><title>Kansas City</title></city>";
}else if(state.equals(“WA”)){
result = "<city><value>seattle</value><title>Seattle</title></city>" .
"<city><value>spokane</value><title>Spokane</title></city>" .
"<city><value>olympia</value><title>Olympia</title></city>";
}else if(state.equals(“CA”)){
result = "<city><value>sanfran</value><title>San Francisco</title></city>" .
"<city><value>la</value><title>Los Angeles</title></city>" .
"<city><value>web2</value><title>Web 2.0 City</title></city>" .
"<city><value>barcamp></value><title>BarCamp</title></city>";
}else if(state.equals(“ID”)){
result = "<city><value>boise</value><title>Boise</title></city>";
}else{
$result = "<city><value></value><title>No Cities Found</title></city>";
break;
}
result ='<?xml version="1.0" encoding="UTF-8" ?>' .
"<cities>" . $result . "</cities>";
<%=result%>
}
12
XML 예제 (JSP)
서버 데이터를 XML 형식으로 주
어 전송하는 예제이다 .
13.
JSON 예제 (HTML)
functiongetCities( ) {
if(xmlhttp.readyState == 4 && xmlhttp.status == 200) {
log("INFO responseXML is ",xmlhttp.responseXML);
var hdrs = xmlhttp.getAllResponseHeaders( );
log("INFO headers are ", hdrs);
try {
var citynodes = xmlhttp.responseXML.getElementsByTagName('city');
for (var i = 0; i < citynodes.length; i++) {
var name = value = null;
for (var j = 0; j < citynodes[i].childNodes.length; j++) {
var elem = citynodes[i].childNodes[j].nodeName;
var nodevalue = citynodes[i].childNodes[j].firstChild.nodeValue;
if (elem == 'value') {
value = nodevalue;
} else {
name = nodevalue;
}
}
document.forms[0].elements[1].options[i] = new Option(name,value);
}
} catch (e) {
logDebug("DEBUG error message is", e.message);
}
} else {
document.getElementById('cities').innerHTML = 'Error: No Cities';
}
}
//]]>
JSON 예제 (HTML)
다른 부분은 위 예제 소스와 동일
하여 다른 부분인 getCities() 함수
에 대하여 설명하겠다 .
getCities() 함수는 서버에서 전송
한 데이터 ( 응답 문자열 ) 를 적절
히 파싱하여 콤보박스의 옵션을
생성하는 기능을 한다 .
13
14.
JSON 예제 (JSP- 서버컴포넌트 )
<%@page contentType="text/html;charset=euc-kr"%>
<%
request.setCharacterEncoding("euc-kr");
String state=request.getParameter("state");
어온다
String result=“”;
// 검색 문자열을 받지 않으면 검색을 수행할 수 없다 .
if(state=null) {
<%="<city>No State Sent</city>";%>
} else {
if(state.equals(“MO”){
result = "[ { 'value' : 'stlou', 'title' : 'St. Louis' }, " .
“{ 'value' : 'kc', 'title' :' Kansas City' } ]";
}else if(state.equals(“WA”)){
result = "[ { 'value' : 'seattle', 'title' : 'Seattle' }, " .
" { 'value' : 'spokane', 'title' : 'Spokane' }, " .
" { 'value' : 'olympia', 'title' : 'Olympia' } ]";
}else if(state.equals(“CA”)){
result = "[ { 'value' : 'sanfran', 'title' : 'San Francisco' }, " .
" { 'value' : 'la',
'title' : 'Los Angeles' }, " .
" { 'value' : 'web2', 'title' : 'Web 2.0 City' }, " .
" { 'value' : 'barcamp', 'title' : 'BarCamp'
} ]";
}else if(state.equals(“ID”)){
result = "[ { 'value' : 'boise', 'title' : 'Boise' } ]";
}else{
result = "[ { 'value' : '', 'title' : 'No Cities Found' } ]";
}
<%=$result%>
}
// 클라이언트가 전송한 데이터를 읽
JSON 예제 (JSP)
Result 데이터를 보면 다음과 같이
[{}] 데이터를 감싸는 것을 볼 수
있다 .
이를 JSON( 자바스크립트 객체
표기법 ) 이라 한다 .
object{} or object {string:value...}
array[] or object [value,value...]
14
15.
Ajax POST 방식폼 데이터 전송
<HTML 폼의 요소 >
<input type=“text” name=“state”>
<input type=“text” name=“state2”>
Ajax Post 방식 폼 데이터 전송
function postForm( ) {
// 서버에 폼 데이터를 전송하는 함수
var state = document.forms[0].elements[0].value;
var state2 = document.forms[0].elements[1].value;
var qry = "state=" + state + “&” + “state2=” + state2;
// 폼에 전송할 (name,value) GET 방식처럼 name=value&name=value 형식으로 입력하면 된다 .
var url = 'combobox.jsp';
xmlhttp.open('POST', url, true);
//POST 방식으로 url 전송
xmlhttp.onreadystatechange = getCities;
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//content-type 헤더는 urlencoded 폼으로 변경되고 , 질의는 send 메소드로 전송된다 .( 폼으로 전송시 꼭 써야 함 )
//application/x-www-form-urlencoded 사용하여야 qry 의 name, value 가 폼 데이터로 변환됨 .
xmlhttp.send(qry);
}
15
16.
Ajax POST 방식폼 데이터 전송
- Ajax Post 방식 폼 데이터 전송시 문제점 -
Ajax Post 방식 폼 데이터 전송
문제점
x-www-form-urlencoded 를 사용할 경우 데이터가 유니코드로 변환 된다 .
그래서 폼 데이터가 한글일때는 잘못된 값이 들어가게 된다 .
이것을 해결하려면
1. 먼저 톰캣 5.x 버젼대에서는 server.xml 의 인코딩 옵션 부분
URIEncoding="euc-kr" 을 사용하지 않고 , useBodyEncodingForURI="true“ 로 설정하여야 한다 .
이렇게 하게 되면 Tomcat 4.x 처럼 request.setCharacterEncoding() 의 값을 따라가게 할 수 있다 .
2. 그리고 헤더 설정 부분도 다음과 같이 수정 해주어야 한다 .
xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded;charset=UTF-8");
3. 그리고선 HTML 파일의 스크립트 postForm() 부분에서 전송할 폼의 value 를 encodeURI(),
encodeURIComponent(), escape() 등을 이용하여 보내주면 된다 .( 세 함수는 인자값을 유니코드화 시켜주는 기능을 가지
고 있다 .)
예제 :
function postForm( ) {
var state = encodeURI(document.forms[0].elements[0].value);
var state2 = encodeURI(document.forms[0].elements[1].value);
}
스트럿츠를 사용할 경우
스트럿츠를 사용할 경우엔 위의 방법이 통하지 않을것이다 . 왜냐하면 대부분의 스트럿츠 환경에서는 인코딩 필터가 ‘ EUCKR’ 이 기본으로 설정 되있기 때문이다 .
이 문제를 해결하려면 여러가지 방법이 있을것이다 .
그 중 몇 개의 예를 들어 보도록 하겠다 .
1.web.xml (/webapp/WEB-INF/web.xml) 에 설정되있는 인코딩 필터 셋팅을 전부 지워주는것이다 . 이렇게 하게 되면 페이지에
서 지정한 charset 이용이 가능하다 .
2.web.xml 에서 필터의 파라메터로 헤더의 값 ( 예 : AjaxFlag) 을 받게 하여 값을 파싱하여 charset 을 바꿔주는 것이다 .
예를 들어 헤더에 AjaxFlag = true 일 경우 EncodingFilter 클래스에서 CharacterEncoding(charset) 을 UTF-8 로 지정하게 끔
동작 하도록 만들어주는 것
16
17.
Ajax 라이브러리 소개
1.Prototype
무료로 다운 할수 있고 유명한 라
이브러리로 , Ruby on Rails(RoR)
개발 환경에 통합되어 있기도 하
다.
http://prototype.conio.net
2
1
2. Script.aculo.us
Prototype 을 기반으로 만든 라이
브러리고 , 많은 기능이 추가 되어
세련된 효과를 낼수 있을뿐 아니
라 더 높은 수준의 인터랙션을 제
공한다 .
( 사용하려면 여러 개의 자바스크
립트 파일을 로드해야한다 .)
http://wiki.script.aculo.us/scriptaculous/s
3. Rico
사브레 항공 솔루션 개발팀이 만
들었고 비상업적 용도로 자유롭게
사용할 수 있다 .( 아파치 라이센스
적용 ) 기능이 사용하기 쉬우며 ,
영화 같은 효과를 줄수 있다 .
http://openrico.org/rico/home.page
3
17