JSONP にはコールバック用のパラメータが必要です
JSON では、異なるドメインのサーバからデータを取得することができないません。 また、現在の URL かそのサブドメインからしかデータを取得することができません。 従って、同じサーバであっても、/ranking から /json の JSON データを取得することはできません。
このようなセキュリティポリシー問題を解消するために JSONP が用いられます。
- クライアントサイド
jQuery の $.ajax() や $.getJSON() で JSONP リクエストを作成する場合、URI パラメータは以下のような形式になります。
// getJSON() の場合 $.getJSON( '/json?callback=?', // URI {}, // クエリパラメータ function(json) { // コールバック関数 }); // ajax() の場合 $.ajax({ url: '/json?callback=?', data: {}, // クエリパラメータ dataType: 'jsonp', // データ型 success: function(json) { // コールバック関数(成功時) } });
URI は /json, ?, callback=? から構成されます。
最初の ? は URL とクエリパラメータの区切り文字です。 最後の ? はクエリパラメータ callback の値ですが、これは jQuery が自動的に代入してくれます。
- サーバサイド
Google App Engine ではプリインストールされている simplejson モジュールが利用できます。
クライアントサイドで指定したクエリパラメータ callback の値を取得し、レスポンスに付加します。
from google.appengine.ext import webapp from django.utils import simplejson class JSONHandler(webapp.RequestHandler): def get(self): # クエリパラメータ callback の値を取得する callback = self.request.get('callback') if not callback: return # JSON のデータ作成 data = { 'name': 'shobon', 'url': 'shobon.com' } # simplejson で Python 型を JSON 型に変換 json = simplejson.dumps(data, ensure_ascii=False) self.response.headers['Content-Type'] = 'application/json' self.response.out.write('%s(%s)' % (callback, json)) # JSONP
パラメータ callback の値が xxx だった場合、レスポンスとして返すテキストは xxx({"name": "shobon", "url": "shobon.com"}) のようになります。
JSON データを callback の値で囲むのが JSONP のルールです。