원문 : http://ejnahc.tistory.com/261
간단하게 말하자면 어떤 사이트에서 다른 사이트에 있는 정보를 Ajax로 가져오려고 하며 Cross-Domain Policy(동일 출처 정책)에 의해 막히게 된다. 도메인이 서로 다른 경우에는 아예 접근을 하지 못하게 되는 것인데, 이를 해결하기 위해 이런 꼼수들이 있다.
- 자신의 웹 서버에 데이터를 요청하고 해당 웹 서버가 실제 가져올 서버에 요청을 전달하는 프록시 서버 역할
- 프레임 요소를 사용하여 현재 웹 페이지 내에 새 영역을 만든 후 GET 요청을 사용하여 컨텐츠를 가져오기
- JSONP 사용하기
function showPrice(data) {
console.log(data);
}
// now load the script
var url = “ticker.js”; // URL of the external script
// this shows dynamic script insertion
var script = document.createElement('script');
script.setAttribute('src', url);
// load the script
document.getElementsByTagName('head')[0].appendChild(script);
미리 showPrice라는 함수를 정의해두고, //now load the script 에서 그 함수를 호출하 는 것이다. 여기서의 함수는 일종의 콜백 함수라 생각하면 되겠고, 그 함수를 호출하는 부분에서 콜백 함수를 호출하는데 그 파라미터를 새로 불러온 (외부 서버에 존재하는) script에서 처리한다. 외부 서버에 존재하는 script 자체를 불러오는데는 Cross-Domain Policy랑은 관련이 없기 때문이다.
요약하자면 다른 도메인에 있는 자바스크립트를 동적으로 삽입하여 해당 자바스크립트 파일로부터 JSON 데이터를 받아오는데, 받아온 데이터를 처리하는 콜백 함수를 미리 만들어 두고 그 함수 내에서 받아온 데이터를 처리하게끔 하자는 것이다.
jQuery에서는 JSONP를 지원하기 위해 getJSON이라는 메서드를 지원한다. 사용방법은 아래와 같다.
jQuery.getJSON("http://www.yourdomain.com/jsonp/ticker?symbol=IBM&callback=?",
function(data) {
alert("Symbol: " + data.symbol + ", Price: " + data.price);
});
실제 www.yourdomain.com... 이하 URL에서는 이런 식으로 처리를 해준다. (예를 들어)
$jsonData = getDataAsJson($_GET['symbol']);
echo $_GET['callback'] . '(' . $jsonData . ');';
// prints: jsonp1232617941775({"symbol" : "IBM", "price" : "91.42"});
즉 jsonp1232617941775 라는 함수를 호출하는데, 그 파라미터로 json 객체를 넘겨주게 된다. 내부 구조가 어떻게 되어있는지는 모르겠지만 저 꼴로 보아 내부적으로 eval을 수행하는 것 같다. (eval("jsonp...") 와 같이) 저 함수 이름은 getJSON에 있는 callback=? 와 대응되는데, jQuery가 ? 기호를 인라인 함수를 호출하는 생성된 함수 이름으로 바꿔준다고 한다.
예를 들어 실제 서비스 중인 JSONP 서비스 (API)를 보자.
와 같은 경우, 출력물을 보면 우리가 넘겨준 jsoncallback 파라미터에 따라 호출할 함수 이름이 달라지는 것을 확인할 수 있다.
따라서 JSONP를 사용하면 외부 서비스와의 연동이 굉장히 쉬워진다. 하지만 JSONP에도 단점이 있는데,
- 서비스에서 제대로 된 값을 넘겨주지 않는 경우 아무 일도 일어나지 않는다.
- 신뢰할 수 없는 서비스와 함께 사용할 경우 매우 위험할 수 있다.
(호스트 하는 웹 어플리케이션이 다양한 공격에 노출될 수 있다.)
'programming > javascript' 카테고리의 다른 글
자바스크립트 이벤트 호출 확인 (0) | 2013.04.09 |
---|---|
자바스크립트의 this는 개발자 의도대로 바인딩되지 않습니다. (0) | 2013.02.12 |
자바스크립트에서 함수는 변수 이다. (0) | 2013.02.05 |
extend, eval, load (0) | 2013.01.06 |
let (0) | 2012.12.27 |