サービスクライアント
概要
ROCOCOライブラリのサービスクライアントは、Rococo.clの下にあり、
XmlHttpRequestでは、Rococo.cl.xml、JSONPでは、Rococo.cl.jsonpを、それぞれ使います。
クライアント設定クラス
ROCOCOサービスクライアントの振る舞いを設定するために、次に示すクラスが用意されています。
- Rococo.cl.UrlSetting
- サービス呼び出しに必要な情報、すなわち、URL(パラメータを除く)、予約パラメータ、メソッド、JSONP関数名を設定します。
- Rococo.cl.DecisionSetting
- サービスの成否を示すXMLパスまたはJSONPオブジェクトパスを設定します。
リクエスト発行とコールバック関数
リクエストは、requestメソッドで発行します。コールバック関数は、
function(s,r)で固定されており、sはTrue/False型の終了ステータス、
rは、結果オブジェクト(XmlHttpRequestを出してもJavaScriptオブジェクトに変換されています)
が入ります。
クライアント設定
Rococo.cl.UrlSetting
UrlSettingの生成は、次のように行います。
var urlsetting = new Rococo.cl.UrlSetting( url_body,rparams, method, caller );
コンストラクタ引数は次の通りです。
- url_body
- サービスURLのうちパラメータを除いた部分
- rparams
- ユーザ作成スクリプトによって、必ず指定しなければならないパラメータ(パラメータ名と値の組)
- method
- 'get'や'post'などのHTTPメソッド
- caller
- JSONPで応答が得られた際に実行される関数名を指定するパラメータ名。一般にはサービス側で指定されています。JSONPのみ有効です。
たとえば、utmzone.phpの場合には、次のように指定します。
- url_body
- 'http://www.finds.jp/tsrv/utmzone.html'
- rparams
- null
- method
- 'get'
- caller
- 'jsonp'
Rococo.cl.DecisionSetting
DecisionSettingの生成は、次のように行います。
var decisionsetting = new Rococo.cl.DecisionSetting( decisionpath, decisionvalue, errorpath );
- decisionpath
- 成功かどうかを決定する値が収められているパス
- decisionvalue
- decisionpathにある値が成功であると判断するための値
- errorpath
- 失敗した場合のエラーメッセージが収められているパス
ここで言う「パス」は、ルートから順に見た要素名(XMLの場合)またはプロパティ名(JSONPの場合)の配列です。
たとえば、ルート要素直下にある status という名前の要素の値で、計算の成否が伝えられる場合には、decisionpathは{'status'}になります。
また、resultという名前の要素の中にあるstatusという名前の要素の場合は、{'result','status'}になります。
リクエスト
ROCOCOクライアントからリクエストを出すメソッド request で、次のような引数を取ります。
obj.request( params, callback );
- params
- パラメータ文字列。すべてのパラメータ名と値の組み合わせは & でつなげなければなりません。
- callback
- コールバック関数。次のような引数を取ります。
function(status,result);
- status
- 成功か失敗かを true/false で示します。
- result
- 成功時はJavaScriptオブジェクトが渡されます。失敗時はエラーメッセージ文字列が渡されます。
XmlHttpRequestとJSONP
XmlHttpRequestとJSONPは、サービスとの通信に欠かせないものです。
XmlHttpReuqest
XmlHttpRequestによって、WWWコンテンツのページ遷移から独立してJavaScriptからHTTPサーバにコネクションを張ることができます。 これによって、あるサービスから得たデータを他のサービスに渡したり、ページ遷移なくクエリを出すことができるので、複数のサービスを複合させたコンテンツを作成でき、 また、ページ遷移を行わないので、通信時間が短く済み、軽快に動作します。
XmlHttpRequestは、多くのブラウザでは組み込みクラスとして用意されていますが、 Internet Explorer では、ActiveXとして提供されていました(このためオブジェクト生成方法が他のブラウザと異なります)。
XmlHttpRequestの欠点とJSONP
しかし、XmlHttpRequestは、通常はブラウザのセキュリティポリシに抵触するため、クロスドメインの通信ができません。 これは、そのコンテンツが公開されているホスト以外で提供されているサービスは利用できない、ということです。
そこで、JSONPが考案されました。JSONPは、scriptエレメントをHTML文書に挿入することで通信します。 ブラウザは、scriptエレメントが挿入されると、src属性で指定したURLに従ってJavaScriptファイルを取得しようとします。 この際、ドメインによるセキュリティポリシは通常は適用されません。取得できたら即座に実行します。
JSONPによってクロスドメインでリモートのファイルを取得することができるようになります。 しかし、JavaScriptとして取得する必要があります。そこで、取得するファイルは、コールバック関数を呼び出し、その実引数にサービスの応答をJavaScriptで表現できるデータ構造で記述されたオブジェクトにします。
これで、クロスドメインでサービスの応答を取得することは可能になりましたが、次のようにいくつか問題があります。
- コンテンツ作成者が意図した通りのファイルを取得できなかった場合には、エラーを検知することができません。このため、取得したファイルJavaScriptとして正しくない場合、 ファイルに記述されたコールバック関数名が間違っている場合等においては、JSONP通信を開始したまま放置されます。
- HTTP応答の情報を取得できません。このため、Not Found によるエラーなのか、Internal Service Error かといった分析ができません。
ROCOCOライブラリでのJSONP対応
ROCOCOライブラリではJSONP通信をリクエストした場合には、タイマをセットして、指定された時間経過してなお応答しなかった場合には、 タイムアウトをコールバック関数に渡すようにしています。エラー分析は全くできませんが、リクエストしたまま放置されることはありません。
ROCOCOライブラリでのリクエスト方法
ROCOCOライブラリでは、XmlHttpRequestおよびJSONPは、ほぼ同じ要領でリクエストできます。
まず、リクエストオブジェクトを生成します。
// XmlHttpRequestの場合 object = new Rococo.cl.xml.XmlRequest( title, urlset, decisionset ); // JSONPの場合 object = new Rococo.cl.jsonp.JsonpRequest( title, urlset ,decisionset);
ここで、titleはそのリクエストを示す文字列(エラーメッセージ作成等に使います)、 urlsetはRococo.cl.UrlSetting オブジェクト、decisionsetはRococo.cl.DecisionSetting オブジェクトをそれぞれ示します。
クライアントのサンプル
ここでご紹介するサンプルは、utmzone.phpへのサービスアクセスを行っています。 XML版とJSONP版とでは、HTMLファイルは同じですが、JavaScriptコードが異なっています。
順に、HTMLファイル、XML版JavaScriptファイル、JSONP版JavaScriptファイルを示します。
HTMLファイル(XML, JSONP 共通)
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml" lang="ja" xml:lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<script type="text/javascript" src="http://www.finds.jp/rococo/b2/rococo.js"></script>
<link rel="stylesheet" type="text/css" href="http://www.finds.jp/rococo/b2/rococo.css" />
<script type="text/javascript" src="sample.js"></script>
</head>
<body>
<form action="javascript:void(0)">
<p>北緯 <input type="text" size="40" value="34.50165844222924" id="lat" /></p>
<p>東経 <input type="text" size="40" value="133.3843445777893" id="lon" /></p>
<p><input type="submit" onclick="utmZone()" /></p>
</form>
</body>
</html>
XML版
応答の書式がJSONP版と仕様が異なるため、スクリプトも若干異なっています。
function utmZone() {
var lat = document.getElementById('lat').value;
var lon = document.getElementById('lon').value;
var req_url = new Rococo.cl.UrlSetting(
'http://www.finds.jp/ws/utmzone.php'
);
var req_dec = new Rococo.cl.DecisionSetting(
['utmzone','status'],
200,
['utmzone','result','utmzone']
);
var req = new Rococo.cl.xml.XmlRequest('utmzone',req_url,req_dec);
req.request('lat='+lat+'&lon='+lon, utmZoneResult);
}
function utmZoneResult(s,r) {
if( s ) {
alert(r.utmzone.result.utmzone);
}
else {
alert(r);
}
}
実行結果は次の通りです。
JSONP版
応答の書式がXML版と仕様が異なるため、スクリプトも若干異なっています。
function utmZone() {
var lat = document.getElementById('lat').value;
var lon = document.getElementById('lon').value;
var req_url = new Rococo.cl.UrlSetting(
'http://www.finds.jp/ws/utmzone.php',
null,
null,
'jsonp'
);
var req_dec = new Rococo.cl.DecisionSetting(
['status'],
200,
['result','utmzone']
);
var req = new Rococo.cl.jsonp.JsonpRequest('utmzone',req_url,req_dec);
req.request('lat='+lat+'&lon='+lon, utmZoneResult);
}
function utmZoneResult(s,r) {
if( s ) {
alert(r.result.utmzone);
}
else {
alert(r);
}
}
実行結果は次の通りです。
プリセットサービス
ROCOCOライブラリでは、いくつかのサービスについてアクセスするための設定(Rococo.cl.UrlSetting, Rococo.cl.DecisionSetting)のオブジェクトを事前に生成しています。 ここでは、これをプリセットサービスと呼びます。
次に示すプリセット設定は、それぞれはオブジェクトで、urlプロパティ(Rococo.cl.UrlSettingオブジェクト)、decisionプロパティ(Rococo.cl.DecisionSettingオブジェクト)を持っています。
- Rococo.jp.cl.jsonp.rgeocode
- Rococo.jp.cl.jsonp.municipalitylist
- Rococo.jp.cl.jsonp.geocode
なお、XML版のプリセット設定は用意していません。
プリセット設定は、クライアントオブジェクト生成時に利用します。rgeocode.phpをリクエストするためのオブジェクトを生成する例を次に挙げます。
// rgeocodeリクエストオブジェクトの生成
object = new Rococo.cl.jsonp.JsonpRequest(
'rgeocode',
Rococo.jp.cl.jsonp.rgeocode.url,
Rococo.jp.cl.jsonp.rgeocode.decision,
);

