ajax and json and jsonp

はじめまして。
mk front-end-engineerの田中塁です。
f:id:ruirui_0923:20121023151903j:plain

twitter APIjquery を使って、tweet情報をjson形式で受け取って自前のjsファイルで加工して表示するという事をしていたが、とあることからjsonで受け取ったファイルをローカルで保存して、そこを参照してjsonを取得するという風に書き換えなければいけないことになった。


そこで、ちょっと詰まったところがあったので備忘録的なことを含め書いておく。

ちなみにtwitter APIとのajax通信の部分は下のコード

	$.ajax({
		type: 'get',
		url: 'http://search.twitter.com/search.json?q=from%3Akeio_news&callback=?',
		dataType: 'jsonp',
		success: function (obj) {
			twitterTl(obj);
		},
		error: function () {
			alert('通信が失敗しました');
		}
	});

@keio_newsからtweet情報を取得するというものだ。

f:id:ruirui_0923:20121023142113p:plain

上のようなjson形式のデータが返ってくる。

このjsonファイルをsearch.jsonという名前で保存して
コードのurl,dataTypeの部分を以下のように書き換えた。

		url: '../js/search.json',
		dataType: 'jsonp',

だが、これでは動作してくれなかった。

		url: '../js/search.json',
		dataType: 'json',

という風に記述しなくてはいけなかった。



ajax通信でwebAPI等クロスドメインからjsonを参照する時はdataTypeを'jsonp'、ローカルに保存してあるjsonを参照するときは'json'とするみたいだ。。。


なぜだ。。。

両方jsonpではダメか。

webAPIの時 OK
ローカルの時 ダメ

理由
jsonpではファイルの形式は、通常

(callback関数名:例callback) (
{
    jsonデータ
});

というようにcallback関数の引数としてjsonが与えられる。

しかし、callback=?としてjsonpデータ取得してみたところ、

jQuery182029029840137809515_1350971301001(
{
completed_in: 0.032,
max_id: 260592894669381630,
max_id_str: "260592894669381633",
.......
......
..
});

というように呼び出される関数名が「jQuery適当な数字」になってしまう。
そのため、ローカルにjsonp形式でファイルを保存しようとしてもcallbackとして呼び出される関数名がわからないため保存のしようが無いのでjsonpとしては使えないのである。

hogehoge(
{
    jsonデータ
});

上のようにjsonpファイルを書いて、

		url: '../js/search.json?callback=hogehoge',
		dataType: 'jsonp',

という風にしてもダメだった。これは元データがjsonのためcallback関数名は指定できないからだとおもわれます。




両方jsonではダメか

ローカルの時 OK
webAPIの時 ダメ

理由
そもそも、クロスドメインのセキュリティの関係上、他のドメインにあるjsを読み込めない。


だからjson with paddingというような名前の通りjsonをjsに挟み込むようなjsonpの利用が推奨されている。




結論

ローカルではjson,webAPIではjsonpを使いましょう。