JSONP(ジェイソンプ)とは | 意味や読み方など丁寧でわかりやすい用語解説

JSONP(ジェイソンプ)の意味や読み方など、初心者にもわかりやすいように丁寧に解説しています。

作成日: 更新日:

読み方

日本語表記

ジェイソニピー (ジェイソニピー)

英語表記

JSONP (ジェイソンピー)

用語解説

JSONPは「JSON with Padding」の略称であり、ウェブブラウザのセキュリティ上の制約である「同一オリジンポリシー」を回避して、異なるドメイン間でデータを送受信するための技術的な手法の一つである。主に、ウェブページ上のJavaScriptから、そのページが置かれているサーバーとは別のサーバーにあるAPIを呼び出し、データを取得する目的で利用されてきた。JSONPの基本的なアイデアは、HTMLの<script>タグが持つ、異なるドメインのサーバーからでもJavaScriptファイルを読み込んで実行できるという性質を利用することにある。これにより、本来であれば同一オリジンポリシーによって直接アクセスが制限される外部ドメインのデータを、間接的に取得することが可能となる。ただし、現在ではより安全で高機能なCORS(Cross-Origin Resource Sharing)という仕組みが標準化されたため、新規開発でJSONPが採用されることは少なくなり、主に古いシステムやAPIをサポートするために用いられる歴史的な技術と位置づけられている。

JSONPが必要とされる背景には、ウェブブラウザに実装されている「同一オリジンポリシー」という重要なセキュリティ機能が存在する。このポリシーは、あるオリジンから読み込まれた文書やスクリプトが、他のオリジンのリソースにアクセスすることを原則として禁止するものである。ここで言うオリジンとは、プロトコル、ホスト(ドメイン名)、ポート番号の組み合わせによって定義される。例えば、「http://example.com」から読み込まれたJavaScriptは、「https://api.example.com」や「http://another-domain.com」にあるリソースに対して、`XMLHttpRequest`オブジェクトを用いた非同期通信(Ajax)で直接アクセスしようとすると、ブラウザによってブロックされる。これは、悪意のあるウェブサイトが、ユーザーがログインしている別のサイトの情報を不正に盗み見るような攻撃を防ぐための仕組みである。しかし、ウェブアプリケーションが進化するにつれて、外部のサービスが提供するAPIを利用してデータを取得し、自サイトのコンテンツと組み合わせる(マッシュアップする)需要が高まった。この同一オリジンポリシーの制約を安全に回避する必要性から、JSONPのような技術が考案された。

JSONPの具体的な仕組みは、クライアント側とサーバー側の連携によって実現される。まず、クライアント側のJavaScriptは、取得したデータを使って実行したい処理を「コールバック関数」として定義しておく。次に、データを要求するAPIのURLに対して、このコールバック関数名をクエリパラメータとして付与してリクエストを送信する。例えば、handleResponseという名前のコールバック関数を定義した場合、APIのURLは http://api.example.com/data?callback=handleResponse のようになる。このリクエストはXMLHttpRequestではなく、動的に生成した<script>タグのsrc属性にこのURLを設定し、HTML文書に追加することで行われる。<script>タグによるリソースの読み込みは同一オリジンポリシーの対象外であるため、ブラウザは異なるドメインのサーバーへ問題なくリクエストを送信する。

リクエストを受け取ったサーバー側のアプリケーションは、通常のJSONデータをそのまま返すのではなく、クライアントから指定されたコールバック関数名を使って、JSONデータを引数とするJavaScriptの関数呼び出しの形式の文字列を生成する。上記の例であれば、サーバーは {"id": 1, "name": "Taro"} というJSONデータを返す代わりに、handleResponse({"id": 1, "name": "Taro"}); というJavaScriptコードをレスポンスとして返す。この時、HTTPレスポンスのContent-Typeはapplication/jsonではなくapplication/javascriptに設定される。

クライアント側のブラウザは、このレスポンスをJavaScriptコードとして受け取り、<script>タグの仕組みによって即座に実行する。その結果、あらかじめクライアント側で定義されていたhandleResponse関数が、サーバーから送られてきたJSONデータを引数として呼び出されることになる。このようにして、関数呼び出しという形を借りることで、実質的にクロスドメインのサーバーからデータを取得し、クライアント側のJavaScriptで利用することが可能になる。

この手法にはいくつかの利点と重大な欠点が存在する。利点としては、CORSが標準化される以前の古いブラウザでも広くサポートされていたため、互換性が高い点が挙げられる。一方で、欠点も多い。まず、リクエストは<script>タグのsrc属性を利用するため、HTTPメソッドはGETしか使用できない。そのため、データの作成や更新を行うPOSTやPUTといったメソッドは利用できず、用途はデータの取得に限定される。また、XMLHttpRequestのようにHTTPステータスコードを直接取得できないため、通信エラーの詳細なハンドリングが難しいという問題もある。最も深刻な欠点はセキュリティ上のリスクである。JSONPは外部サーバーから返されたJavaScriptコードを無条件に実行する仕組みであるため、もしAPIを提供するサーバーが悪意のある第三者に乗っ取られた場合、任意のコードがユーザーのブラウザ上で実行されてしまうクロスサイトスクリプティング(XSS)などの脆弱性につながる危険性がある。したがって、JSONPは完全に信頼できるAPI提供元に対してのみ利用するべきである。

現在では、クロスドメイン通信を実現するための標準的な方法としてCORSが推奨されている。CORSは、サーバー側でアクセスを許可するオリジンをHTTPヘッダで明示的に指定することにより、ブラウザが安全性を判断してクロスドメインアクセスを許可する仕組みである。CORSはGET以外のHTTPメソッドにも対応し、エラーハンドリングも容易で、JSONPが持つセキュリティ上のリスクもない。そのため、現代のウェブ開発においてクロスドメイン通信が必要な場合は、まずCORSの利用を検討するべきであり、JSONPはCORSに対応していない古いAPIをどうしても利用しなければならない場合などに限定して用いられる技術となっている。