이 문서의 이용시 주의사항(Attention for this document)

이 페이지는 Prototype 공식 홈페이지의 "Introduction to Ajax" 문서를 한국어로 번역한 문서입니다. 번역 오류정보 및 기타 제안사항은 제안 및 문의사항 페이지를 통해 보내주시기 바랍니다. 이 문서는 원저작자의 공유 조건인 Creative Commons 저작자표시-동일조건변경허락 3.0 Unported에 따라 이용하실 수 있습니다.

본문(Content)

Ajax 기능은 전역 Ajax 객체에 포함되어 있다. Ajax 요청의 전송은 xmlHTTPRequest로, 사용자로부터 안전하게 추상화 되어있는 브라우저 별 차이점을 가지고 있다. Ajax.Request 객체의 인스턴스를 생성함으로써 요청을 활성화할 수 있다.

new Ajax.Request('/some_url', { method:'get' });

첫번째 인자는 요청의 URL이다. 두번째 인자는 해시로 구성되는 옵션이다. 옵션 중 Method는 사용될 HTTP 메소드로 참조되며, 기본값은 POST이다.

(Cross-site scripting 공격을 막는) 보안 문제로 인해 Ajax 요청은 해당 요청을 포함하고 있는 페이지와 동일한 프로토콜, 호스트, 포트번호로 구성된 URL만 허용된다는 사실을 기억하라. 몇몇 브라우저는 임의의 URL을 허용하기도 하지만, 이에 대한 지속적인 지원을 기대하지 말라.

Ajax 응답 콜백(Ajax response callbacks)

Ajax 요청은 비동기식으로, 응답으로 전달되는 데이터를 처리할 콜백이 있어야만 한다는 것을 의미한다. 콜백 메소드는 요청을 생성할 때 해시 옵션으로 전달된다.

new Ajax.Request('some_url',
{
	method:'get',
	onSuccess: function(transport) {
		var response = transport.responseText || "no response text";
		alert("Success! \n\n" + response);
	},
	onFailure: function() { alert('Something went wrong...') }
});

여기서는 성공 또는 실패 경고창을 띄우는데, 응답의 상태에 기반하여 그에 따라 onSuccessonFailure가 호출된다. 이 둘에게 전달된 첫번째 인자는 responseTextresponseXML을 이용할 수 있는 고유의 xmlHttpRequest 객체이다.

콜백을 둘 다 정의할 것인지, 하나만 정의할 것인지, 정의하지 않을 것인지는 사용자에게 달려 있다. 그밖에 사용가능한 콜백은 다음과 같다.

  • onUninitialized
  • onLoading
  • onLoaded
  • onInteractive
  • onComplete
  • onException

다른 콜백을 처리할 때 에러를 만나면 발생하는 onException을 제외하고, 이들 모두는 xmlHttpRequest 전송의 특정 상태와 연결된다.

또한 onXXX 형식의 콜백도 가능한데, XXX는 200이나 404와 같은 HTTP 응답 상태이다. 이것을 사용할 때는 onXXX가 우위를 선점하므로 onSuccess, onFailure는 발생하지 않는다는 것을 명심해야 하는데, 따라서 이것을 사용할 때는 반드시 본인의 작업에 대해 이해를 하고 있어야 한다는 것을 의미한다.

onUninitialized, onLoading, onLoaded, onInteractive 콜백은 아직 모든 브라우저에서 일관되게 동작하지 않는다. 일반적인 상황에서는 이것들은 사용하지 않는 편이 좋다.

매개변수와 HTTP 메소드(Parameters and the HTTP method)

옵션의 parameters 속성을 이용하면 요청을 위한 인자를 넘겨줄 수 있다.

new Ajax.Request('/some_url', {
	method: 'get',
	parameters: {company: 'example', limit: 12}
});

인자는 해시(우선됨)와 (company=example&limit=12)처럼 앰퍼샌드로 구분되는 키-값 쌍 문자열 형태로 전달된다.

인자는 GET, POST 요청 모두에서 사용가능하다. 그러나 GET 요청은 결코 데이터 변경을 유발하지 않는다. 또한 일반적 브라우저는 POST 요청의 응답을 캐시에 저장하는 경우가 거의 없으나 GET 요청에서는 굉장히 흔한 일이다.

Parameters 속성의 주요 용도 중 하나는 Ajax 요청을 이용하여 FORM 내용을 전송하는 것인데, Prototype은 이를 위해서 Form.serialize라 불리는 보조 메소드를 제공한다.

new Ajax.Request('/some_url', {
	parameters: $('id_of_form_element').serialize(true)
});

사용자 임의의 HTTP 요청을 헤더에 포함시킬 필요가 있다면, requestHeaders 옵션을 사용할 수 있다. 그냥 키-값 해시 또는 ['X-Custom-1', 'value', 'X-Custom-2', 'other value']과 같은 1차원 배열을 넘겨주기만 하면 된다.

이런 연유로, (parameters 옵션 이외의) 커스터마이징 부분을 포함하고 있는 POST 객체를 위해서 postBody 옵션이 존재한다. postBody를 사용할 경우 postBody가 body를 대체하게 되어 같이 넘어간 parameters는 무시된다는 점을 인식하라. 따라서 이 옵션의 사용이 정확히 무엇을 의미하는지 파악하고 있어야 한다.

자바스크립트 응답을 평가하기(Evaluating a JavaScript response)

종종 어플리케이션은 자바스크립트 코드로 된 응답을 보내도록 제작된다. 응답의 컨텐츠 타입(content type)이 자바스크립트 MIME 타입과 매치된다면, Prototype은 자동으로 되돌려받은 자바스크립트 코드에 eval()을 적용한다. 특별한 이유가 없다면 사용자가 응답을 직접 처리할 필요는 없다.

다른 경우로, 응답이 X-JSON 헤더를 포함하고 있다면, 이 응답의 내용은 분석처리되어 객체로 저장된 뒤, 콜백의 두번째 인자로 전달될 것이다.

new Ajax.Request('/some_url', { method:'get',
	onSuccess: function(transport, json){
		alert(json ? Object.inspect(json) : "no JSON object");
	}
});

Ajax를 이용하여 적지 않은 분량의 데이터를 가져오되, XML 응답 분석처리에서 비롯되는 부하(負荷)를 피하고 싶은 경우라면 이 기능을 활용하라. JSON은 XML보다 (더 가볍고) 빠르다.

Global responders

Ajax.Responders는 각 Ajax 요청에 대한 정보가 집약되어 있는 객체이다. Ajax.Request에는 특정 상태에서 발생하는 콜백을 등록할 수 있다.

Ajax.Responders.register({
	onCreate: function(){
		alert('a request has been initialized!');
	},
	onComplete: function(){
		alert('a request completed');
	}
});

xmlHttpRequest의 각 전송상태와 연결되는 콜백은 onCreate에 이어서 선언된다. 이처럼 요청을 한 데 모아 기록하는 것은 사용자가 선택한 자바스크립트 로거(logger)를 이용하여 디버깅을 한다던가, 발생가능한 접속 문제에 대해 사용자에게 알려주는 전역 예외 처리기를 만드는 등의 많은 면에서 유용한 점을 제공한다.

Ajax.Updater로 동적으로 페이지 업데이트하기(Updating your page dynamically with Ajax.Updater)

문서의 일부분을 업데이트 하기 위한 HTML을 돌려받기 위하여 Ajax 요청을 생성하는 경우가 자주 있다. Ajax.Request와 함께 onComplete를 사용하면 꽤 수월한 작업이지만, Ajax.Updater를 사용하는 편이 훨씬 쉽게 끝난다!

HTML 문서에 다음과 같은 코드가 있다고 가정해 보자.

<h2>Our fantastic products</h2>
<div id="products">(fetching product list ...)</div>

'products' 블럭은 빈 상태이지만 Ajax 응답으로부터 돌려받은 HTML로 채우려고 한다. 간단한 일이다.

new Ajax.Updater('products', '/some_url', { method: 'get' });

이게 전부다. 더 할 일은 없다. 첫번째 인자로 목적지 엘레멘트(the receiver element)를 넘겨준다는 점을 제외하면, Ajax.Request의 인자와 동일한 인자를 사용한다. Prototype은 Element.update() 메소드를 이용하여 자동적으로 목표 블럭의 내용을 응답내용으로 업데이트할 것이다.

돌려받은 HTML에 스크립트가 포함되어 있다면(inline scripts) 이는 기본설정값에 의해 제거된다. evalScripts 옵션의 값으로 true를 넘겨주면 스크립트가 실행되는 모습을 볼 수 있다.

그러나 에러가 발생하여 서버에서 HTML 대신 에러 메세지를 되돌려준다면 어떻게 될까? 사용자가 컨텐츠를 기대하는 자리에 에러 메세지를 끼워넣고 싶지 않은 경우가 있을 수 있다. Prototype은 이 문제에 대해 편리한 해결책을 제공하는데, 첫번째 인자로 목표 위치(actual container)만 넘겨주는 대신 { success:'products', failure:'errors' }와 같은 Hash 형식으로 2개의 엘레멘트를 넘겨줄 수 있다. 모든 것이 제대로 동작한다면 success 위치에 내용이 출력될 것이고, 에러는 failure 위치에 출력될 것이다. 이 기능을 이용하면 더욱 사용자 친화적인 인터페이스를 구성할 수 있다.

또한 해당 위치에 내용을 덮어쓰지 않고 Insertion.Top 또는 Insertion.Bottom을 사용할 때처럼 해당 위치의 윗부분이나 아래부분에 내용을 삽입하도록 할 수도 있다. Ajax에 insertion 매개변수의 값으로 insertion 객체를 넘겨주기만 하면 된다.

new Ajax.Updater('products', '/some_url', {
	method: 'get',
	insertion: Insertion.Top
});

Ajax.Updater는 전달받은 객체를 이용하여 'product' 블럭 안에 돌려받은 HTML를 삽입할 것이다. 멋지게.

Ajax.PeriodicalUpdater로 요청 자동화하기(Automate requests with the Ajax.PeriodicalUpdater)

Ajax.Updater의 근사함을 발견했겠지만, 이것을 이용하여 서버에서 오는 내용을 주기적으로 처리해야 할 경우가 있다. Prototype 프레임워크는 이와 관련된 기능 역시 포함하고 있는데, 이것은 Ajax.PeriodicalUpdater라 불리는 것으로, 기본적으로 이것은 Ajax.Updater를 일정간격을 두고 실행하는 것이다.

new Ajax.PeriodicalUpdater('products', '/some_url',
{
	method: 'get',
	insertion: Insertion.Top,
	frequency: 1,
	decay: 2
});

새로운 옵션인 frequencydecay가 보인다. Frequency는 요청이 만들어지는 초 단위 간격이다. 이것이 1초라는 것은 Ajax 요청이 매초마다 일어난다는 것을 의미한다. 기본값은 2초이다. 어플리케이션이 이런 식으로 동작하는 것은 사용자에게는 행복한 일이 될 수 있지만, 만약 충분히 많은 수의 브라우저가 동시에 한 페이지에 접근한다면 서버에는 큰 부하가 걸릴 것이다. 이것이 decay 옵션이 존재하는 이유이다. 현재의 응답값이(response body) 그 전 값과 동일하다면 그 때마다 frequency는 decay 값에 의해 곱해진다(multiplied). 이 경우에 첫번째 Ajax 요청은 1초 후, 2번째는 2초 후, 3번째는 4초, 4번째는 8초 후에 일어난다. 물론, 서버가 항상 다른 내용을 돌려준다면 decay는 효과를 발휘하지 않을 것이다. 이 엘레멘트는 내용이 그다지 자주 갱신되지 않고 서버가 몇 번이고 동일한 내용을 반환할 경우에만 작동한다.

반복간격이 짧은 상황에서는(having frequency falloff) 요청의 전체 횟수가 감소하는 효과가 있기 때문에 서버의 부하를 적지않게 줄여줄 수 있다. 서버 로드를 모니터링할 때 이 엘레멘트를 테스트해보라. 이 엘레멘트의 효과를 적용하고 싶지 않다면 (디폴트 값이기도 한) 1을 넘겨주거나 단순히 이 엘레멘트를 생략해 버리면 된다.

더 많은 학습을 원한다면 Ajax.Request, Ajax.Updater, Ajax.Options를 보라.

트랙백 목록(Trackback List)

이 글에 대한 감상/의견을 트랙백으로 보내주세요.

URL
이 글에는 트랙백을 보낼 수 없습니다