JSONP にはコールバック用のパラメータが必要です

JSON では、異なるドメインのサーバからデータを取得することができないません。 また、現在の URL かそのサブドメインからしかデータを取得することができません。 従って、同じサーバであっても、/ranking から /jsonJSON データを取得することはできません。
このようなセキュリティポリシー問題を解消するために 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 のルールです。