작년 10월에 Ajax.Request에 대해서 포스팅을 한번 한적 있는데 추가적으로 작성할 것도 있고 또 그때보다 더 알게 된 것도 있기 때문에 다시한번 포스팅한다.
기본적으로 Ajax1라 하는 것은 비동기통신을 뜻하고 웹페이지를 새로 갱신하지 않고 서버세 접속해서 특정 부분만을 갱신하는 기법이다. 이 기법을 통해서 웹이 크게 발전했고 XMLHttpRequest를 사용한 것으로 대표되기는 하지만 Ajax는 비동기로 통신하는 기법자체를 의미하지 반드시 XMLHttpRequest를 사용해야만 하는 것은 아니다.
어쨌든 Ajax라는 게 인기를 끄는데는 XMLHttpRequest가 그 중심에 있는데 솔직히 간단하지는 않다. 하지만 자바스크립트 프레임워크를 쓰면 꽤나 간단하게 사용할 수 있는데 XMLHttpRequest에 대한 처리부분을 프레임워크에서 대부분 처리해 주기 때문이고 여러가지 간면한 메서드를 제공하고 있다. 자바스크립트 프레임워크를 쓰는 이유에 있어서 Ajax만으로도 그 편리함은 충분하다고 생각한다.
// example of an AJAX/XMLHttpRequest JavaScript function from Wikipedia
function ajax(url, vars, callbackFunction)
{
var request = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
request.open("POST", url, true);
request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
request.onreadystatechange = function()
{
if (request.readyState == 4 && request.status == 200)
{
if (request.responseText)
{
callbackFunction(request.responseText);
}
}
};
request.send(vars);
}
나는 prototype.js 프레임웍을 사용하는데 이런 내부의 복잡한 로직을 Ajax.Requst의 호출만으로도 간단히 해결해 준다. Requset가 prototype.js의 기본적인 Ajax사용이라고 생각되는데 프로토타입 프레임워크의 사이트에서 제공하는 API를 보면
new Ajax.Request(url[, options])
위처럼 정의되어 있다. []로 묶인 것은 사용해도 되고 안해도 되는 것이다.
// Ajax.Request 사용하기
new Ajax.Request("ajax.jsp",
{
method:'get',
parameters : { par:Code },
onLoading : function() {
},
onSuccess : function(returnValue)
{
var returnValue = returnValue.responseText;
},
onFailure : function() {
},
onComplete : function() {
}
});
위처럼 간단하게 Ajax.Request를 사용할 수 있다. 옵션은 JSON 표기법을 사용해서 필요한대로 적어댈 수 있고 필요없는 것은 적지 않아도 상관없다. parameters에서 par라는 이름으로 Code라는 변수를 지정해서 넘겨준다. 물론 스트링을 직접 주려면 홑따옴표('')로 묶어주면 되고 Code라는 변수를 사용했으므로 당연히 상단에서 Code라는 변수를 정의해 놓았어야 한다. 이건 ajax.jap?par=code 처럼 넘겨준것과 같다. 물론 code는 변수의 값이 넘어가야하는거지만....
onLoading은 Ajax통신을 시작할 때 발생하고 onSuccess는 통신이 성공되었을 때 발생하고 onFailure는 통신이 실패했을 때 onComplete는 통신이 성공하든 실패하든 통신이 끝났을 경우에 발생한다. 각 부분에 원하는 기능을 코딩하면 된다. 이밖에도 더 제공하는 옵션이 있는데 사용해 보지 않아서 아직은잘 모르겠다.
여기에 프로토타입에서는 Ajax.Updater라는 것도 제공하고 있는데 API에는 다음과 같이 정의 되어 있다.
new Ajax.Updater(container, url[, options])
Updater는 말 그대로 Ajax통신이 끝난 뒤에 container에 해당 내용을 집어넣는 구조로 되어 있다. responseText를 받아서 innerHTML을 하는 대신에 Updater를 사용해서 간단하게 처리할 수 있고 container에는 해당엘리먼트의 id를 스트링 형태로 넘겨주면 된다.
new Ajax.Updater('elementId', 'ajax.jsp')
위처럼 아주 간단하게 elementId안에 내용을 업데이트 할 수 있다. 물론 여기에 옵션이 필요하다면 Request에서와 동일하게 옵션을 넣어 줄수 있다.
// Ajax.Updater 사용하기
new Ajax.Updater({success:'elementId'}, 'ajax.jsp', {
method:'get',
parameters : {
x:code1,
y:code2
},
onLoading: function() {
},
onSuccess : function(returnValue) {
},
onComplete : function() {
}
});
위에서와 다르게 container부분에 JSON형태로 넘겨주면서 success라는 key값을 넣어주었는데 이는 통신이 성공했을 때만 'elementid'에 내용을 업데이트 하라는 것이다. {success:'elementId', failure:'messagebox'}처럼 넘겨주면 통신이 성공하면 elementId를 실패하면 messagebox를 업데이트 하게 된다.
여기서 주의점은 onSuccess와 onComplete의 업데이트 타이밍의 차이인데 실제로 통신해서 받아온 내용이 갱신되는 시점은 onComplete가 실행되는 시점이다. onSuccess에서는 통신이 완료되기는 하지만 실제 내용이 페이지에 갱신되지는 않는다. 그렇기 때문에 Ajax통신을 통해서 받아온 내용에 들어있는 엘리먼트를 사용하기 위해서는 onSuccess가 아니라 onComplete에서 코드를 넣어주어야 다룰 수 있다. onSuccess에서는 아직 해당 엘리먼트가 페이지에 삽입되지 않았기 때문에 엘리먼트를 찾지 못해서 에러가 나게 되고 Ajax의 특성상 오류메시지도 나오지 않기 때문에 해결하기도 골치 아프다.
- Asynchronous JavaScript and XML [Back]
안녕하세요^^ 또 글을 남기게 되네요 ㅠㅠㅠㅠ
이번에 네이버 검색 api 를 이용해서 글을 띄우려고하는데요
xml파일을 만들어 위와 같이 예제를 작성하고 ajax.request(url 이 url에 파일명.xml
을 쓰면 제대로 xml 내용을 가져오는데 http://apis.daum.net/search/vclip?q=daum&apikey=DAUM_SEARCH_DEMO_APIKEY 와 같이.. 다음 ,네이버 api 의 url을
쓰면 못가져오는지 혹시 알수있을까요?ㅠㅠ
무응답인 상황인데 . 자꾸 귀찮게 해드려서 죄송합니다 ㅠㅠ^^
JavaScript에는 동일출처원칙(same origin policy)라는 것이 있습니다. 보안을 위한 샌드박스라고 할 수 있는데요. 그래서 JavaScript는 자신이 불려진 URL가 같은 URL에만 요청을 보낼 수 있습니다.
ajax도 JavaScript이기 때문에 지금 테스트 하시는 페이지의 URL과 다른 URL(네이버나 다음)으로는 요청을 보낼 수 없습니다. 실행은 되지만 실제 액션이 되지 않죠. 샌드박스에 막혀버립니다.
2가지 해결책이 있는데요.
이걸 해결하기 위한 기술이 jsonp입니다. jsonp에 대한 설명까지 하긴 좀 길어서요. prototype.js를 쓰시는것 같은데 저도 쓴지 오래되서 최신버전에서는 어떤지 모르겠지만 jquery를 쓰신다면 $.json같은걸(문법이 맞나 모르겠군요.) 자동으로 jsonp를 알아서 처리해줍니다. 아니면 jsonp를 찾아보셔서 직접 구현하셔도 됩니다. 제 기억에는 prototype.js에는 없었던것 같습니다.
아지만 서버에서 프록시를 할 수 있습니다. openAPI를 javascript에서 직접 사용하지 마시고 서버에서 네이버나 다음의 API를 호출하고 웹페이지에서는 자신의 서버로 호출해서 결과를 받아오는 방식입니다.
아! 정말로 명쾌한 답변 감사합니다 ^_^ ㅎ
정말로 감사합니다 ㅎㅎㅎㅎ
두가지 방법 모두 해보겠습니다! ㅎㅎ