JSON と JSONP
JavaScript を利用する上で知っておきたいJSONというフォーマット。
JSON(JavaScript Object Notation)
JSONは、JavaScript におけるテキストベースのデータフォーマット(とはいっても別の言語でも利用することは可能)です。eval()関数で評価することで、JavaScriptオブジェクトに変換することができます。
データタイプと表記方法
JSONは、XMLに比べ記述が容易で人間が理解しやすいデータフォーマットです。
データタイプ | 概要 | 例 |
---|---|---|
数値 | 10進数で表記し、整数および小数部、指数部の記述が可能。 | 13.45 |
文字列 | ダブルクォーテーションで囲まれた英数字や記号。改行やタブ、ダブルクォーテーションなどの特殊文字はバックスラッシュ(\)でエスケープする。 | "hello" |
真偽値 | 「真」を意味する true、「偽」を意味する false。 | true |
NULL 文字 | 何らの意味を持つ文字ではないことを示す特殊な文字。 | null |
配列 | 全体を [ ]で囲み、値をカンマ(,)で区切って列挙する。項目を繰り返し表現するのに利用。 | ["Haskell", "Groovy", "Erlang"] |
オブジェクト | 全体を { }で囲み、キーと値のペアをコロン(:)で区切って記述。 | {"name":"shinta", "age":32} {"type" : ["JSON", "XML", "YAML"]} |
JavaScript での利用方法
JSON形式の文字列を JavaScript で利用するのはとても簡単で、eval()関数で JavaScriptのオブジェクトに変換することで利用可能になります。
var jsonData = '{"type" : ["JSON", "XML", "YAML"]}';
var obj = eval('(' + jsonData + ')');
alert(obj.type[1]);
JSONを外部ファイルに記述しておき、XMLHttpRequest を利用して取得することも可能です(XMLHttpRequest部分は jQuery を利用)。
{"type" : ["JSON", "XML", "YAML"]}
$.ajax({ url: "/data/jsonData.json", success: function(jsonText){ var obj= eval('(' + jsonText + ')'); alert(obj.type[1]); });
上記は、XMLHttpRequest を利用して取得したデータを eval()関数で評価していることを説明するためにコードです。実際に jQueryを利用するなら getJsonというメソッドでもっと簡単に扱えます。
$(function(){
$.getJSON("/data/jsonData.json", function(obj){
alert(obj.type[1]);
});
});
しかし、外部のデータを取得する場合、データ以外に悪意を持ったコードを取得するおそれがあるので eval()関数にそのまま渡してはセキュリティー上問題となる可能性があります。そこで、きちんとJSONをパースして利用することが望ましいでしょう。たとえば、json.orgのJSONパーサのJSON.parse()メソッドは引数で渡されたJSONテキストがJSONの仕様に従っているかどうかをチェックし正常なら eval()関数でJavaScriptオブジェクトへの変換を行います(不正なデータの場合は例外を投げます)。
待てよ、初めからデータをオブジェクトとして変数とかに格納した JavaScript を置いて scriptタグで読み込めば Ajaxなんて必要ないんじゃない?
var jsonData = {"type" : ["JSON", "XML", "YAML"]};
<script type="text/javascript" src="http://www.example.com/data/jsonData.json"></script> <script type="text/javascript"> alert(jsonData.type[1]); </script>
これなら 同一生成元ポリシー(Same Origin Policy)にも影響しないのでクロスドメインでも利用も可能。。。。。でも、これでは、巨大なグローバルデータを作ることにもなりかねないし、変数名が固定されるなど、プログラムで扱うにはスマートではない。そこで JSONP の登場です。
JSONP(JavaScript Object Notation with Padding)
JSONPは、JavaScriptの外部ファイル読込み(scriptタグ)を利用しクロスドメイン間でのデータを扱うことが可能になります。JSONPでは、関数に引数として JSONオブジェクトを指定した形式になります。
myCallback({"type" : ["JSON", "XML", "YAML"]});
これを利用する側は、この関数とおなじ名前の関数を定義(myCallback(jsonData){})しておくことで、データを読み込んだ際にその関数が実行されます。
<script type="text/javascript"> <!-- var myCallback = function(jsonData){ alert(jsonData.type[1]); } --> </script> <script type="text/javascript" src="http://www.example.com/data/jsonData.jsonp"></script>
いろいろなWebアプリケーションに JSONPでデータを提供するような場合、JSONPを出力する API を公開します。この際に、関数名をパラメータとして受け取るようなAPIにすることで、利用側に都合の良い関数名で JSONP を出力することができます。(関数名を JSONPを提供する側に左右されなくて済む。しかし、安全のため関数名は英数字のみ受け付けるようにした方が良い。)
http://api.example.com/service/foobar?callback=yourCallback