JSONPを利用する - JavaScript

JSONPについて紹介します。

サンプル:シンプルなサンプル

サンプルコードから紹介します。

コード

sample.js

JSONPのデータを返すファイルです。MIME Typeの関係で拡張子をjsにしておくとよいです。
apicallback ( { 'name': 'penguin', 'price' : '550' });
解説
apicallback がJSONPの提供するデータへのアクセスのためのインターフェイスとなるコールバック関数です。

Page1.html

JSONPを呼び出すHTMLファイルです。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>

  <script type="text/javascript">
    function apicallback(json)
    {
      alert(json.name);
    };
  </script>
</head>
<body>
  <script type="text/javascript" src="sample.js"></script>
</body>
</html>
解説
  <script type="text/javascript" src="sample.js"></script>
上記がJSONPを呼び出すScriptタグです。JSONPはコールバック関数の呼び出しが記述されているため、すぐに下記のapicallback()関数を呼び出します。
  <script type="text/javascript">
    function apicallback(json)
    {
      alert(json.name);
    };
  </script>


apicallback()関数が呼び出された際に、引数のjsonには、sample.jsに記述された値が渡されます。
{
  'name': 'penguin',
  'price' : '550'
}
のJSONオブジェクトが引数に与えられます。
コールバック関数apicallback()内で、与えられたオブジェクトのnameプロパティの値をalert()で表示します。

実行結果

HTMLファイルをWebブラウザで表示します。アラートダイアログが表示され、JSONPに記述したnameプロパティの値"penguin"が表示されます。

クロスドメインでの利用

JSONPでは、先に紹介したsample.jsを別のドメインに配置することができます。
これは、JSONはXMLHttpRequestを用いてファイルを読み込んでいますが、JSONPでは、外部JavaScriptファイルの読み込みを利用しているためです。
先のHTMLファイルのscriptタグのsrc属性に読み込み先のJSONのURLを記載すれば、他のドメインのJSONPファイルが読み込めます。
Page1.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>

  <script type="text/javascript">
    function apicallback(json)
    {
      alert(json.name);
    };
  </script>
</head>
<body>
  <script type="text/javascript" src="http://subdomain.ipentec.com/datademo/sample.js"></script>
</body>
</html>

サンプル:より実用的な例

先のサンプルコードでは"sample.js"ファイル1つにつき1つのコールバック関数しか呼び出せない実装でした。複数のコールバック関数を切り替える場合は、JSONPのファイルを複数用意する必要があります。APIの個数分ファイルを用意しても良いですが、パラメーターで切り替えられるようにするのも良い方法です。

コード

以下のコードを記述します。

Page2.html

JSONPを呼び出すHTMLページです。
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>

  <script type="text/javascript">
    function api1callback(json)
    {
      alert("価格:"+json.price);
    };
    function api2callback(json) {
      alert("高さ:"+json.height);
    };

    function loadJS(src) {
      var script = document.createElement('script');
      script.src = src;
      document.body.appendChild(script);
    }

  </script>
</head>
<body>
  <input id="Button1" type="button" value="Price" onclick="loadJS('JsonpHandler.ashx?api=price')"/>
  <input id="Button1" type="button" value="Height" onclick="loadJS('JsonpHandler.ashx?api=height')"  />
</body>
</html>
解説
上記のコードではJSONPファイルを動的に読み込んで動作します。動的な読み込みはloadJS()関数で実行されます。scriptタグを作成し、動的にbodyタグ内に書きだすことでJSONPファイルを読み込みます。
JSONPファイルのハンドラでは2種類のAPIがあり、ハンドラapiパラメータの値を指定することで呼び出されるJSONPが変化します。

JsonpHandler.ashx.cs

JSONPを返すジェネリックハンドラーです。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

namespace JsonpDemo
{
  /// <summary>
  /// JsonPHandler の概要の説明です
  /// </summary>
  public class JsonPHandler : IHttpHandler
  {

    public void ProcessRequest(HttpContext context)
    {
      string apiquery = context.Request.QueryString["api"];
      context.Response.ContentType = "application/javascript";

      if (apiquery == "price") {
        context.Response.Write("api1callback({ 'name': 'penguin', 'price': '550' });");
      }
      else {
        context.Response.Write("api2callback({ 'name': 'penguin', 'height': '220' });");
      }
    }

    public bool IsReusable
    {
      get
      {
        return false;
      }
    }
  }
}
解説
ハンドラ-側では、リクエスト時のapiパラメータの値を取得し、値が"price"であれば、api1callbackを呼び出すJSONPを、それ以外であればapi2callbackを呼び出すJSONPを返します。

実行結果

プロジェクトを実行し、Page2.htmlを表示します。下図の画面が表示されます。


[Price]ボタンをクリックするとapi1callback()関数が実行され、アラートダイアログに価格情報が表示されます。


[Height]ボタンをクリックするとapi2callback()関数が実行され、アラートダイアログに高さの情報が表示されます。

補足

JSONPの処理はサーバー側でする必要があるため、CGIなどのサーバー側プログラムで実装する必要があります。
JavaScriptでJSONP側の記述を実装しても、実行はクライアント側になるため、パラメーターの伝達がうまくできません。
著者
iPentecのメインプログラマー
C#, ASP.NET の開発がメイン、少し前まではDelphiを愛用
最終更新日: 2014-08-22
作成日: 2014-08-21
iPentec all rights reserverd.