同一生成元ポリシー (Same Origin Policy) と JSONP とは?
JSONP って何?どんなイイコトがあるの?
JSONP というのは、JSON with padding (付け足し JSON) といい、 JSON (JavaScript Object Notation) を拡張したプログラミングモデルです。 JSONP では、同一生成元ポリシーによる他サーバーへの問い合わせの制限を回避して、 元のサーバーと異なるサーバーへの問い合わせを可能とします。
この資料では、JSONP で回避する問題である「同一生成元ポリシー」について簡単に説明してから、 JSONP におけるプログラミングモデル、アーキテクチャについて具体的に解説します。
この資料を理解するためには、JavaScript のオブジェクトリテラル表記など、 JavaScript のオブジェクト指向プログラミングと、JSON について理解していなければなりません。 ご存じない方は、当サイトの「JavaScript のオブジェクト指向プログラミング」 などを先にお読みください。この資料ではオブジェクトリテラルや JSON そのものについては説明しません。
同一生成元ポリシーとは?
Ajax では基本的に XMLHttpRequest オブジェクトなどを使って、バックエンドで非同期的にサーバーへ問い合わせを行います。 サーバーへの問い合わせ結果を元に、現在表示されている HTML ページの DOM を操作して、そのページに居ながら表示されているコンテンツを差し替えます。 これによって、ページ全体をリフレッシュすることなく、ページを更新できます。
さてその際、実は XMLHttpRequest で問い合わせ可能な範囲には制限があります。同一生成元ポリシー (Same Origin Policy, SOP) といいます。
同一生成元ポリシー の元では、元の URL と同じホストへの問い合わせしかできません。
このため、XMLHttpRequest などで非同期的に他サーバーへの問い合わせをしようとしても処理が失敗します。 セキュリティ上の理由から主要なブラウザでは、現在 SOP が実装されています。
しかしながら、外部データの取り込みと表示を行う場合には、外部サーバーへ問い合わせ、その結果を操作できたらとても便利です。 これを実現するのが、JSONP です。
JSONP ではどうやって、SOP の制限を回避しているの?
JSONP では JSON 文字列によるオブジェクトリテラルの送信に加えて、関数呼び出しを付け足します。
具体的に示します。 JSONP ではサーバーから、次のような文字列を返します。
func1( {"id":1, "firstname":"Keisuke", "lastname":"Oyama"} );
そして、script タグのスクリプトソースには、同一生成元ポリシーが無いことを利用して、 これを script タグから取り込みます。
<script type="text/javascript" src="http://www.example.com/foo.php?id=1"></script>
さて、この状態で別のスクリプトで、オブジェクトを受け取る func1 を定義しておけば、 その func1 が、外部サーバーから返されたパラメータ (上記の場合 {"id":1, "firstname":"Keisuke", "lastname":"Oyama"} という JSON 文字列) を渡されて実行される、ということになります。
このように、通常の JSON 文字列に加えて、関数のコールバックコードが付け足されて返されるタイプのデータを JSONP と呼び、script タグによって SOP の制限を回避することが可能です。