기껏 REST 서버를 구축하여도 만약 해당 서버 어플리케이션의 API를 또 다른 서버에서 호출하여 사용할 경우, 접근 권한 문제가 발생한다.(대충 그려보았다.)
이를 해결하는 다양한 방법들이 존재하는데... 익스플로러 및 어지간한 예전 웹브라우저들까지 모두 지원하려면 JSONP 를 사용하여야 한다.(서버에서 access-control-allow-origin:* 을 헤더에 싣는 방법도 있지만, 최신 웹브라우저에서만 올바르게 동작하며 익스플로러에선 제대로 동작하지 않는다.)
일단, JSONP 에서 요구하는 형태로 결과를 반환하여야하는데 XE2 에 추가된 TDSHTTPWebDispatcher 의 FormatResult 이벤트 메소드를 아래와 같이 만지작거려야한다.
procedure TWebModule1.DSHTTPWebDispatcher1FormatResult(Sender: TObject;
var ResultVal: TJSONValue; const Command: TDBXCommand; var Handled: Boolean);
var
JSONValue: TJSONValue;
begin
if Command.Text = 'TServerMethodsPost.ZipcodeData' then
begin
if GetInvocationMetadata.QueryParams.IndexOfName('callback') > -1 then
begin
Handled := True;
JSONValue := ResultVal;
ResultVal := TJSONArray(JSONValue).Get(0);
TJSONArray(JSONValue).Remove(0);
JSONValue.Free;
end;
end;
end;
6: 해당 요청 메소드인 경우에 한하여 처리한다.
8: JSONP 요청인 지 여부를 callback 파라미터가 있는가로 구분한다.
10 이하: 결과 반환시 result: 어쩌구 부분을 날려버린다.
일단, 단순한 형태로 구성하였고... 해당 서버 어플리케이션의 상황에 따라 보강하면 되겠다. 헌데, 아웃 파라미터인 ResultVal 의 타입이 TJSONValue 인지라 JSONP 가 원하는 결과를 위하여 또 다른 추가 작업을 해줘야한다.
TWebModule 의 AfterDispatch 이벤트 메소드를 다음과 같이 작업한다.
procedure TWebModule1.WebModuleAfterDispatch(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
var
Callback: String;
begin
if Request.QueryFields.IndexOfName('callback') > -1 then
begin
Callback := Request.QueryFields.Values['callback'];
Response.Content := Callback + '(' + Response.Content + ')';
end;
end;
6: JSONP 의 callback 요청인지 판단한다.
8: callback 으로 지정되는 함수의 이름이 랜덤하게 변경되어 요청될 수 있으므로 파라미터 값을 가져와 처리한다.
9: JSONP 가 요구하는 형태로 callback 에서 지정한 함수를 호출하는 형태로 결과값을 반환한다.
마찬가지로 해당 서버의 상황에 따라 보강하면 된다. 클라이언트측 자바스크립트는 jquery 를 사용하여 다음과 같이 호출한다.
(모업체의 우편번호 검색 기능을 REST API 로 호출해보는 샘플이다.)
<!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=UTF-8">
<title>JSONP TEST</title>
<script type="text/javascript" src="http://192.168.0.178:9090/rest/js/jquery-1.7.2.min.js"></script>
<script>
$(document).ready(function(){
$("#testBtn").click(function(){
$.ajax({
url : "http://192.168.0.178:9090/rest/ILPREST.dll/datasnap/rest/TServerMethodsPost/ZipcodeData/구로/1/2",
dataType : "jsonp",
jsonp : "callback",
success : function(d){
$.each(d, function(k, v){
$("#ajax").append("<div>" + k + ": ----------------------------------------</div>");
$("#ajax").append("<div>" + v.SEQ_NUM + "</div>");
$("#ajax").append("<div>" + v.NEW_YN + "</div>");
$("#ajax").append("<div>" + v.ZIPCODE + "</div>");
$("#ajax").append("<div>" + v.SIDO + "</div>");
$("#ajax").append("<div>" + v.SIGUNGU + "</div>");
$("#ajax").append("<div>" + v.EUPMYUNDONG + "</div>");
$("#ajax").append("<div>" + v.BUNJI + "</div>");
$("#ajax").append("<div>" + v.BD_NAME + "</div>");
$("#ajax").append("<div>" + v.SADDRESS + "</div>");
});
$("#ajax").show();
},
error: function() {
alert('error');
}
});
});
});
</script>
<style>
div{margin-bottom:10px;padding:2px;}
#ajax{border:1px solid blue;display:none;}
</style>
</head>
<body>
<button id="testBtn">테스트</button>
<div id="ajax"></div>
</body>
</html>
물론, 해당 html 파일은 다른 서버에 위치하고 있다.
'프로그래밍 > PC' 카테고리의 다른 글
Delphi XE2 에서 DataSnap REST Application Client (0) | 2012.07.13 |
---|---|
dbExpress MySQL 5.1 한글 테이블명 사용 (0) | 2012.06.26 |
Delphi XE2, dbExpress Oracle 10g 연동 (1) | 2012.05.30 |
Interface 요약 #7 (0) | 2012.04.19 |
Interface 요약 #6 (0) | 2012.04.19 |
댓글