Oteto Blogのロゴ

JSONPとは何者か【JSONとの違い・jQuery.ajaxでの利用】

jQueryゴリゴリな環境でJSONPを用いた非同期通信に触れる機会があったが、そもそもJSONPが何者かすら理解してなかったので調べる。

JSONとJSONPの違い

名前からしてJSONを拡張したものかと思っていたが、JSONPはあくまでスクリプト (JavaScript)。

JSON{
  "key1": "value1",
  "key2": "value2"
}
JSONPcb({
  "key1": "value1",
  "key2": "value2",
})

厳密には「返り値であるJSONを引数とした、リクエスト時に指定したコールバックを実行するスクリプト」。

なぜJSONPを利用するのか

他オリジンからデータを取得するため

もしXMLHttpRequestやFetch APIを利用してクロスドメインに非同期通信を行おうとするとCORSの制約を受けてしまう。

<script src="https://example.com/items?callback=cb"></script>

しかし上記のように<script>srcに指定した場合はその制約を受けないので、

  1. クライアント側でリクエスト前にコールバック関数を定義しておき、その関数名をクエリパラメータに付与しリクエストする
  2. サーバ側はレスポンスとして「返り値のJSONを引数にした1の関数」を実行するスクリプトを返す
  3. クライアント側は2のスクリプトを実行する

ことによりデータの取得 (+処理の実行) が可能になり、この仕組みがJSONPと呼ばれる。

jQuery.ajaxを利用する場合

余談だが筆者の場合、前述の仕組みを大して知らなくても簡単にJSONPを用いた非同期通信が実装できた。

$.ajax({
  type: 'GET',
  url: 'https://example.com/items',
  dataType: 'jsonp',
  success(data) {
    alert(data);
  },
});

というのもjQuery.ajax()はJSONP形式に対応しており、上記のように書くだけで下記の一連の処理をjQueryがよしなにやってくれる。

  1. コールバック関数名を指定したクエリパラメータcallback=jQueryxxx_yyyをリクエスト先URLに追加
  2. 1のURLに向けた<script>を生成しDOMツリーへ追加 (3の実行後に削除される)
  3. レスポンス内のJSON部分がObjectにパースされ、success()に渡される