【JavaScript入門】JSONP

 JSONP(JSON with Padding)は、クロスオリジン制約(同一オリジンポリシー) を回避して 別ドメイン から JSON データを取得するために考案された古典的テクニックです。
 仕組みはシンプルで、サーバーに 「スクリプトとして実行可能な文字列」(=コールバック関数呼び出し)を返させ、ブラウザ側では <script> タグ経由で読み込むだけ――ブラウザは JavaScript ファイルの読み込みにドメイン制限を課さないため、この抜け道が成立します。

1.JSON と JSONP の比較

項目JSONJSONP
取得方法fetch / XMLHttpRequest など<script src="…">
クロスオリジン対応CORS 必須不要(スクリプト扱い)
返却フォーマット純粋な JSON 文字列callback({...}) の JS コード
エラーハンドリングcatch()失敗検知が難しい(onerror など工夫が必要)
主な用途近年の Web API旧式 API、レガシー環境

1.1. コールバック関数

クエリ文字列で ?callback=myFunc のように渡し、サーバーは

myFunc({ ...JSONデータ... });

を返します。ブラウザはスクリプトとして評価し、myFunc が即時実行されるわけです。

1.2. セキュリティ上の注意

  • 受け取るコードを そのまま実行 するため、XSS と同じリスクがある。
  • 近年は CORS 対応 API が主流で、JSONP は推奨されない。

2.クライアントとサーバの役割

ステップクライアント(ブラウザ)サーバー
コールバック関数名を URL で指定受け取った関数名を使い JS 文字列生成
<script src> を動的挿入callback(JSON) をレスポンス
スクリプト実行 → 関数発火

3.サンプルプログラム

 ファイル名

  • jsonp-demo.html(ページ)
  • menu-jsonp.js(サーバーが返す JS)

ファイル名: jsonp-demo.html

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8" />
  <title>📡 JSONP デモ</title>
  <style>
    body{font-family:"Segoe UI",sans-serif;margin:2rem;background:#f6fbff}
    h1{text-align:center;font-size:1.8rem;margin-bottom:1rem}
    #list{padding:1rem;border:1px solid #ccc;border-radius:8px;background:#fff}
    .item{margin:.2rem 0}
  </style>
</head>
<body>
  <h1>📡 JSONP デモ</h1>
  <p>メニュー(JSONP で取得):</p>
  <div id="list">読込中...</div>

  <script>
  // ➀ JSONP が呼び出すコールバック
  function renderMenu(data){
    const box = document.getElementById("list");
    box.textContent = "";                    // クリア
    data.menu.forEach(m => {
      const div = document.createElement("div");
      div.className = "item";
      div.textContent = `${m.name} - ¥${m.price}`;
      box.appendChild(div);
    });
  }

  // ➁ <script> を動的挿入(別ドメインでも OK)
  (()=>{
    const s = document.createElement("script");
    s.src = "./menu-jsonp.js?callback=renderMenu"; // ← サーバにコールバック名を伝える想定
    document.body.appendChild(s);
  })();
  </script>
</body>
</html>

ファイル名: menu-jsonp.js(サーバー側で生成)

// 本来はサーバーが生成して返す JS コード
renderMenu({
  "menu":[
    {"name":"ホットコーヒー","price":450},
    {"name":"アイスコーヒー","price":450},
    {"name":"チーズケーキ","price":500}
  ]
});

ポイント

  • ブラウザにとっては単なる JavaScript。読み込まれた瞬間 renderMenu() が実行される。
  • ファイル名は固定でも、実運用ではバックエンドが 動的にコールバック名を書き換えて応答 する。

ブラウザの出力例

4.プログラム解説

  1. コールバック関数 (renderMenu)
    引数 data にサーバー送信のオブジェクトがそのまま渡ってくる。DOM 操作でリストを描画。
  2. スクリプト動的生成
    document.createElement('script') ならクロスオリジンでも読み込み可能。
  3. menu-jsonp.js
    サーバーはクエリの callback 値を埋め込み、callback(JSON) を返すだけ。
  4. パラメータ名の慣習
    多くの API は callback / cb などでコールバック文字列を受け取る。

まとめ

 JSONP は CORS が整備される前の回避策 として広まりましたが、現在はセキュリティ・エラーハンドリング面で課題が多く、まずは CORS を検討すべきです。それでもレガシー API との連携や、学習用途で「スクリプト1本でデータ取得」を体験するには良いサンプルになります。今回のコードを手元で動かし、<script> タグがネットワーク越しに“実行可能 JSON” を取得する流れを確認してみましょう。