2006年9月20日 (水)

XMLHttpRequestを使わずにデータを受信する

XMLHttpRequestを使ったAjaxでの通信は、セキュリティ上の制限により他ドメインのサーバーにはアクセスできません。
サーバー側のプログラムを自分で記述できる場合は、一旦中継してデータを取得し好きな形式に変換するプログラムを書けばよいのですが、 例えばこのブログのようにJavaScriptしか記述できない場合はそうもいきません。

クライアントがXMLHttpRequestを使わずに他ドメインのサーバーからデータを取得できれば…ということになるわけですが、それを実現する 方法の1つとして、サーバーが結果をJavaScriptのコードで返すというものがあります。

例えば、
http://www.hoge.com/service.aspx?param=xxxxx
のようにリクエストすると、paramの内容に応じた結果をJSONデータを含むJavaScriptコードで返してくれるサービスがあった場合、 クライアント側では、
<script type="text/javascript" src="http://www.hoge.com/service.aspx?param=xxxxx"></script>
という風にしてJavaScriptコードを取り込めば、ドメインとは無関係にデータを利用できます。

scriptタグのsrc属性に指定するURLは他ドメインであっても問題ないという特性を利用したもので、 ちょうど、imgタグのsrcに指定する画像ファイルはどこのサーバーにあっても問題なく画像が表示されるのと同じですね。

このscriptタグをdocument.createElementで動的に生成すれば、XMLHttpRequestを使った場合と同様に動的にデータを取得して表示することが 可能になります。
ただし、その場合は、JavaScriptのコードが読み込み終わった時点で関数を呼び出すなどして読み込みが完了したことを通知しなければ、 クライアント側ではデータを処理できません。


わかり辛いと思いますので、少し具体的に例を書いてみます。

http://www.hoge.com/service.aspx?callback=handle&param=xxxxx
とリクエストすると、
handle({'result':{'item1':'value1'}});
という結果を返すサービスがあったとします。
URLパラメータのcallbackには通知を受ける関数名を指定します。

このサービスを利用する際、クライアントは以下のようなコードでデータを受信することが出来ます。

function getData()
{
    var script = document.createElement('script');
    script.src = 'http://www.hoge.com/service.aspx?callback=handle&param=xxxxx';

    document.body.appendChild(script);
}

function handle(data)
{
    alert(data.result.item1);
}
ボタンを押すなどのイベント時に getData() を呼び出すと、"value1" が表示されます。

こういった利用方法を想定してサーバーが返すデータはJSONP(JSON with Padding)と呼ばれていて、Yahoo! US、Amazon、Flickrなどは すでにこの形式でのサービスも提供しています。

でも、JavaScriptコードを返すということで、セキュリティ上好ましくないという意見もあります。

| | コメント (0) | トラックバック (0)

2006年8月 4日 (金)

AjaxでJSONを利用する

このところFlex2のネタばかりでしたので、久しぶりにJavaScriptのネタです。
AjaxでJSONを利用するサンプル

Ajaxでデータを受信する際、構造化されたデータが欲しい場合は多いです。
Ajaxの"x"はXMLのXなので、XMLデータを使うのが王道なのかもしれません。
実際、XMLデータは色々な環境で利用できますし、構造を定義しやすいのですが、JavaScript標準の機能のみで処理するのはとても面倒です。
このような場合、JSONというフォーマットが便利です。
JavaScriptでは、オブジェクトを生成する際に、
var data = 
{
    title : 'Title',
    url : 'URL'
};
のように記述することが出来ます。
この title や url は data のプロパティとなり、data.title や data["title"] のようにアクセスできます。
上記のサンプルの { から } までの部分の記述をJSONと呼び、JavaScriptではこの形式のデータをテキストとして受信した後、eval関数を使って 動的にオブジェクトを生成することが出来ます。

実際にAjaxで受信したJSONデータからオブジェクトを生成するサンプルは以下のようになります。
Ajaxの通信にはprototype.jsを利用しています。
var url = 'json.txt';
var opts = {
    method : 'get',
    onComplete : showData
};

new Ajax.Request(url, opts);


function showData(r)
{
    var data = eval('(' + r.responseText + ')');
    alert(data.title);
}
とても簡単ですね。
JSON を eval に渡す際には ( ) で囲む必要があります。

XMLほど汎用的でなくてよいと割り切るなら、JSONも検討してみてはいかがでしょうか。
ただし、JavaScriptとしてそのまま実行されてしまいますので、注意は必要です。

| | コメント (0) | トラックバック (1)

2006年7月 5日 (水)

Spry framework for Ajax

Adobeが提供しているJavaScriptライブラリに、Spry framework for Ajaxというものがあります。
使い方が他の多くのライブラリとは異なり、JavaScriptのコードは最小限のものしか記述せず、 HTMLに細工をしてサーバーのXMLデータをバインドするといった感じで、雰囲気としてはASPXに サーバーコントロールのタグを記述してバインドするような感じですかね。
BSDライセンスのもと、フリーで利用可能です。
詳細については、また後日書いてみたいと思います。

Flash Player 9もリリースされ、Flex 2のリリースも近いようですので、楽しみですね。

| | コメント (0) | トラックバック (0)

2006年6月28日 (水)

prototype.js で Ajax

prototype.jsはJavaScriptのライブラリで、色々と便利な機能を提供していますが、 やはり、このライブラリのAjaxの機能が目当てという方が多いんじゃないでしょうか。
実際、XMLHttpRequest関係のブラウザ毎の差異を吸収してくれて、とても簡単に利用できます。

以下のコードはサーバーからデータを受信するものですが、たったこれだけでOKです。
function showData(res)
{
    alert(res.responseText);
}

function getData()
{
    var url = "test.txt";
    var options = {method:"GET", onComplete:showData};
    new Ajax.Request(url, options);
}


アクセスできるURLは、セキュリティの制限により同一のドメインのみに限られています。
optionsの指定は、JSONフォーマットとか言われたりしますが、キーと値のペアをカンマで区切って指定します。
他に指定できるoptionとしては、リクエストする際に渡すパラメータを指定するparametersや、通信の同期・非同期を指定するasynchronousなどがあります。
asynchronousのデフォルト値はtrueになっており、何も指定しなければ非同期通信となります。
onCompleteでは、通信が完了した際に呼ばれる関数を指定しています。
この関数には引数としてXMLHttpRequestオブジェクトが渡されますので、例のようにresponseTextで値を取り出します。
new Ajax.Request(url, options)の部分は、私は最初は少し違和感を感じましたが、この1行でリクエストを送信します。

この他、HTMLの要素の中身のみを更新する目的で利用するAjax.Updaterというクラスもあります。
function updateData()
{
    var url = "test.html";
    var options = {method:"GET"};
    new Ajax.Updater("ElementId", url, options);
}


ほとんどAjax.Requestの時と同じです。
Ajax.Updaterの最初の引数には、中身を更新する要素のIDまたはインスタンスそのものを指定します。
test.htmlには、
<span style="color:red;"><b>Hello Ajax!</b></span>
と書いてあり、通信が完了すると自動的に受け取った値を要素に挿入するといった動作になります。
したがって、サーバーが返す値はHTMLタグである必要があります。
上の実行例ではbuttonタグのIDを指定していますので、実行するとボタンのキャプションが変わります。

| | コメント (0) | トラックバック (0)