カーリルの図書館APIによる東京都の図書館情報(JSONP)を、jQueryのAjax通信によって取得します。
※HTTPS化に伴い、現在本記事内のデモ画面は利用できない状態です。
Ajaxを利用して外部データをリクエストする場合、セキュリティの関係上そのリクエストは同じドメイン上にしかできません。これをクロスドメイン制約と呼びます。そこで利用されるのがJSONP(JSON with Padding)です。
スポンサーリンク
JSONPとは?
JSONPを利用すればAjaxによって外部データを取得することができますが、これはscriptタグの仕組みと同じです。例えばjQueryを読み込む際のscriptタグを見て下さい。ドメインをまたがり(クロスドメイン)外部ファイルを読み込んでいます。これと同様の仕組みを利用したのがJSONPによるAjax通信です。
scriptタグ
1 |
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script> |
今回扱う以下のようなJSONデータは、
1 |
[{"category": "SPECIAL", "city": "千代田区", "short": "農林水産政策研究所"}, {"category": "SPECIAL", "city": "千代田区", "short": "国会図書館"}] |
コールバックでラップすることによって、JSONPとして扱えるようになります。例えば以下はcallbackという名前でラップしているJSONPです。
1 |
callback[{"category": "SPECIAL", "city": "千代田区", "short": "農林水産政策研究所"}, {"category": "SPECIAL", "city": "千代田区", "short": "国会図書館"}] |
下記のデモ画面ではカーリルの図書館APIにリクエストした東京都千代田区の図書館情報(JSONP)を、jQueryを利用してAjax通信をおこなっています。
jsonp_ajax.html(デモ画面)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
<!DOCTYPE html> <html> <head> <title>JSONP</title> <meta charset="utf-8"> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script> <script type='text/javascript'> $(document).ready(function(){ $("#submit_bt").click(function(){ $.ajax({ type: 'GET', url: 'http://api.calil.jp/library?appkey=24c965k3e9fd373278501e2ac2b282kk', data:{ pref:'東京都', city:'千代田区', format:'json' }, dataType: 'jsonp', jsonp: 'callback',//コールバックパラメータ名の指定 //jsonpCallback: 'testCallback',//callback関数名を自分で指名した場合 }) .done(function(data){ $.each(data,function(i, item){ $("#jsonp").append(item.formal + ' <a href=" ' + item.url_pc + ' " target="_blank"> ' + item.url_pc +'</a><br />'); }); /* for(var i=0; i < data.length; i++){ $("#jsonp").append(data[i].formal + ' <a href=" ' + data[i].url_pc + ' " target="_blank"> ' + data[i].url_pc +'</a><br />'); } */ }) .fail(function(data){ $("#jsonp").append("エラーです"); }); }); }); </script> <head> <body> <input type="submit" value="千代田区にある図書館情報をリクエストする" id="submit_bt" /> <div id="jsonp"></div> </body> </html> |
6行目
jQueryのバージョンはHosted Librariesを参照
15行目
appkeyには、カーリルの図書館APIを利用するためのアプリケーションキーを設定します。以下のページから取得することができます。またAPIの仕様については「図書館API仕様書」を参照して下さい。
カーリル APIダッシュボード
21行目
dataTypeについて
返ってくるデータの型を指定します。
22行目
jsonpについて
通常JSONPを取得するリクエストをおこなう場合、URLにcallbackという名のパラメータにコールバック関数名を指定します(パラメータとは下記のURLで言えばformatやpref、cityなどの部分)。カーリルのAPIではformatにJSON形式を指定すれば、デフォルトで&callback=callback(callbackという名のパラメータにcallbackという関数名を指定)が設定されています。
1 |
http://api.calil.jp/library?appkey=◯◯◯&format=json&pref=東京都&city=千代田区&callback=callback |
もしcallbackという名前のパラメータを利用していないAPIの場合は、その名前をjsonpオプションに指定しておく必要があります。例えば下記のように、コールバック関数名を指定するパラメータにexampleCallbackという名前が利用されているとします。
1 |
http://example.co.jp/hoge?appkey=◯◯◯&format=json&exampleCallback=コールバック関数名 |
このような場合、jsonpオプションには「 jsonp:exampleCallback, 」と指定しなければいけません。
23行目
jsonpCallbackについて
jQueryを使ったAjaxでは、コールバック関数名を特に指定せずにリクエストした場合、自動でコールバック関数名が生成されます。もし自分でコールバック関数名を決めたい場合はjsonpCallbackオプションを利用します。
特にコールバック関数名を指定しない場合、
下記の例では「jQuery222032393539301119745_1458786388145」という名が自動で付けられているのが分かります(Safariのデバッグ画面)。
例えば、もしコールバック関数名にtestCallbackという名を自分で指定した場合、
1 2 3 4 5 6 7 8 9 |
url: 'http://api.calil.jp/library?appkey=24c965k3e9fd373278501e2ac2b282kk', data:{ pref:'東京都', city:'千代田区', format:'json' }, dataType: 'jsonp', jsonp: 'callback',//コールバックパラメータ名の指定 jsonpCallback: 'testCallback',//callback関数名を自分で指名 |
testCallbackという名のコールバック関数名のJSONPが返ってきます(Safariのデバッグ画面)。
27〜29行目
each関数で返ってきたデータ(JSON形式)を表示させています。32〜34行目の繰り返しによる表示と同じです。返ってくる図書館データのキーの種類に関しては下記の関連ページをご参照下さい。今回はformal(公式の図書館名)とurl_pc(図書館のURL)を取得しています。
XMLをパースする[simplexml_load_file][カーリルAPI]
まとめ
あらためてJSONPを利用したAjax通信の流れを内部的な仕組みを含めてまとめてみます。
1.URLのcallbackパラメータにコールバック関数名を指定しリクエストする。
2.サーバ(API)からJavaScriptのソースコードが返ってくる。
3.そのソースコードの関数(コールバック関数)をHTML上で実行する。
今回作成した例では、
callbackパラメータにjQueryは
「jQuery222032393539301119745_1458786388145」という生成した名前のコールバック関数名を付けて、カーリルにリクエストし、返ってきた以下のJavaScriptコードを取得し、実行しています。
1 |
jQuery222032393539301119745_1458786388145([{"category": "SPECIAL", "city": "千代田区", "short": "農林水産政策研究所", 〜省略 |
その他関連ページ
JSONデータを取得する[json_decode][カーリルAPI]