2009年5月28日

JavaScript

JSONPを使ってJavaScriptだけでマッシュアップ

  • このエントリーをはてなブックマークに追加
こんにちは、Yahoo!地図の開発を担当しています前田博敏です。
今回は、JavaScriptから外部サイトのWeb APIを直接呼び出すことができる、JSONPという手法について紹介させていださきます。

JSONPとは


JSONPとは、JavaScriptの外部ファイル読み込み(「script」タグとその「src」指定)を利用して、ドメインの異なる外部サイトのデータを読み込む手法のことを言います。

JSONPを利用するには、呼び出される側のWeb APIがJSONP形式に対応している必要があります。
Yahoo!デベロッパーネットワークでは、現在のところローカルサーチAPIショッピングAPIが、JSONP形式に対応しています。

プロキシを用意せず、JavaScriptだけでマッシュアップ


JavaScriptでさまざまなWeb APIをマッシュアップして、Ajaxと呼ばれるような動的なWebアプリケーションを作っている方は多いかと思います。
Ajaxの実装方法として、XMLHttpRequestを用いた方法が一般的によく知られていますが、この方法ではブラウザの制限があるために、ドメインの異なるURLのWeb APIを直接呼び出すことができません。

そのため、外部のWeb APIをプロキシするプログラムを用意する、といった方法で対応されている方も多かったかと思います。

Web API側がJSONP形式に対応していれば、こういったサーバーサイドのプログラムを一切書くことなく、JavaScriptのみでマッシュアップアプリケーションを作ることが出来てしまいます。
ちょっとコードを試したいだけであれば、テキストエディタで書いたHTML+JavaScriptのコードをローカルコンピュータ上に保存し、Webブラウザで閲覧するだけで動作を確認することもできてしまいます。

実際にJSONPを使ってみる


それでは、実際にJSONPを使ったコードを書いてみます。
ここではローカルサーチAPIを利用して、入力された施設の住所を表示するプログラムを書いてみます。
作成するソースコードと、実際に動作するサンプルはこの章の最後に掲載しています。

まずは、JSONPの呼び出し関数を用意しましょう。
今回は独自に書きますが、jQueryや、YUIといったフレームワークライブラリを利用することでも、JSONP形式のAPIを呼び出すことが可能です。
function callJSONP(url) {
  var target = document.createElement('script');
  target.charset = 'utf-8';
  target.src = url;
  document.body.appendChild(target);
}
次にWebAPIリクエストの構築です。
appidには、Yahoo!デベロッパーネットワークで取得したアプリケーションIDを指定してください。
var appid = '<あなたのアプリケーションID>';
var query = document.getElementById('query').value;
var url = "http://map.yahooapis.jp/LocalSearchService/V1/LocalSearch?appid=" + appid + "&p=" + encodeURI( query ) + "&o=json&callback=showResult";
例えば、テキストボックスに「東京ミッドタウン」が指定された場合のリクエストURLは下記のようになります。
http://map.yahooapis.jp/LocalSearchService/V1/LocalSearch?appid=<あなたのアプリケーションID>&p=%E6%9D%B1%E4%BA%AC%E3%83%9F%E3%83%83%E3%83%89%E3%82%BF%E3%82%A6%E3%83%B3&o=json&callback=showResult
その結果、下記のようなJSONP形式のコードが返されます。
showResult({"Count":"1","ViewCount":"1","Query":"\u6771\u4eac\u30df\u30c3\u30c9\u30bf\u30a6\u30f3","Item":[{"Category":"Landmark","Title":"\u6771\u4eac\u30df\u30c3\u30c9\u30bf\u30a6\u30f3","Address":"\u6771\u4eac\u90fd\u6e2f\u533a","AddressLevel":"0","DatumTky97":{"Lat":"35.66258056","Lon":"139.73418889"},"DatumWgs84":{"Lat":"35.665818701569","Lon":"139.73095880233"},"Url":""}]})
このままだと見づらいので、ローカルサーチAPIのレスポンスフィールドの解説を参照していただくか、
XML形式のAPI結果を確認しながら、プログラムを組んでいただくと良いかと思います。

最後に、この結果を受け取り、住所を表示する関数を定義します。
function showResult( result ) {
  if ( result.Count > 0 ) {
    alert( result.Count + "件の結果が見つかりました。\n" +
          result.Item[0].Title + "の住所は" + result.Item[0].Address + "です。" );
  } else {
    alert( "検索結果が見つかりませんでした。" );
  }
}
これで、施設名を入力しその住所を表示するプログラムを書くことができました。

完成したコードは以下のようになります。
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="ja">
<head>
<meta http-equiv="content-script-type" content="text/javascript">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<title>JSONPを使ってJavaScriptだけでマッシュアップするサンプル</title>
</head>
<body>
<input name="query" id="query" value="" >
<input type="button" value="実行" onclick="showAddress()"  >
<script type="text/javascript">
<!--
//住所を表示する
function showAddress() {
  var appid =  'あなたのアプリケーションID';
  var query = document.getElementById('query').value;
  var url = "http://map.yahooapis.jp/LocalSearchService/V1/LocalSearch?appid=" + appid + "&p=" + encodeURI( query ) + "&o=json&callback=showResult";
  callJSONP( url );
}

//JSONPを実行する関数
function callJSONP(url) {
  var target = document.createElement('script');
  target.charset = 'utf-8';
  target.src = url;
  document.body.appendChild(target);
}

//JSONPの結果として実行される関数
function showResult( result ) {
  if ( result.Count > 0 ) {
    alert( result.Count + "件の結果が見つかりました。\n" +
          result.Item[0].Title + "の住所は" + result.Item[0].Address + "です。" );
  } else {
    alert( "検索結果が見つかりませんでした。" );
  }
}
-->
</script>
</body>
</html>

実際に動作させたサンプルとソースコードのダウンロードはこちらです。
サンプル ダウンロード

JSONPのセキュリティ


JSONPは、Web APIが返したレスポンスの内容を、クライアント側が直接JavaScriptとして実行します。
そのため、JSONP形式のAPI提供者は、悪意のあるJavaScriptコードを返すことがないように対策をしておく必要があります。
Yahoo!デベロッパーネットワークのAPIでは、callbackのパラメータに指定できる文字列に制限をするなどの対策を行っています。

通常Web APIの提供者側が万全の対策をすべき所ではありますが、悪意のあるJavaScriptコードが実行される可能性が潜んでいないか、JSONPを利用する側も(一般的なXSS脆弱性の対策としても)常に意識してコードを組むようにすべきかと思います。

まとめ


JSONPを利用して、JavaScriptのみで外部サイトのWeb APIを呼び出し、マッシュアップアプリケーションを作成する方法を解説しました。
Yahoo! JAPAN以外にも、JSONP形式のAPIを提供しているサービスは多数存在します。
また、米Yahoo!が提供しているYQLなど、通常のWeb APIやHTMLを、JSONPに変換するサービスなども出てきています。

ぜひ皆さんも、JSONPをうまく活用して、JavaScriptで手軽に高度なマッシュアップアプリケーションの開発を楽しんでみてください。

最後に、夏に公開を予定しています地図・地域情報開発のためのプラットフォーム「OpenLocalPlatform(仮称)」では、JavaScriptからご利用いただけるAPIを大幅に強化する予定です。こちらもあわせまして、どうぞよろしくお願いいたします。


Yahoo!デベロッパーネットワークはこちら

Yahoo! JAPANでは情報技術を駆使して人々や社会の課題を一緒に解決していける方を募集しています。詳しくは採用情報をご覧ください。

  • このエントリーをはてなブックマークに追加