Hatena::ブログ(Diary)

kanonjiの日記 RSSフィード

http://kanonji.info/blog/ 2013年2月頃に移転しました。

2010-04-27

jQuery.getJSON()で別ドメインのJSONPなデータを読み込む時の注意

jQuery.getJSON(url, data, callback);
$.getJSON(url, data, callback);

jQuery1.2以降で、かつAPI側が対応*1していればですが、jQuery.getJSON() で別ドメインにあるJSONPデータを読み込めます。

JSONPを返すAPIというのは、どこかに仕様があるのか暗黙の習慣なのかは知らないけど、APIのURIに callback=foo*2 といった引数を付ける事になります。

jQuery.getJSON() でもcallback=? をつけると説明する記事がちらほらありますが、ちょっと誤解しやすい気がします。

自分は勘違いしました。

$.getJSON('http://search.twitter.com/search.json?callback=?',
  {
    q: "#jquery"
  },
  function(data, status){
    $.each(data.results, function(i, item){
      console.log(item.text);
    });
  }
);

Twitter Search APIを例にしたコードです。

jQuery.getJSON() で JSONPを読み込むには、URIに callback=? を付けます。

ここで重要なのは ? です。

この ? は、SQLのプレースホルダーみたいなもので、そのまま ? を書かないといけません。

解説記事であまり深く触れてないところが結構あって、最初は自分でコールバック関数名を指定できるのかと思いましたが、それは勘違いでした。


jQuery.getJSON() でJSONPを読み込もうとすると、callback=? は callback=jsonp1272137974675 の様なコールバック関数名に置き換えられます。

そしてjsonp1272137974675() が呼ばれてJSONデータが、jQuery.getJSON()の第3引数であるコールバック関数*3に引数で渡されます。

Same-Originポリシー

同じドメインのデータにしかアクセスできないというポリシー。

これがあるから、JSONはJSONPという形で読み込む必要があります。

Exception: uncaught exception: [Exception... "Access to restricted URI denied"  code: "1012"

Firefoxで別ドメインのJSONを、そのまま読み込もうとすると、この様な例外が発生します。

引数の書き方を変えてみてどうなるか

通る例
$.getJSON('http://search.twitter.com/search.json?callback=?&q=%23jquery',
  function(data, status){
    $.each(data.results, function(i, item){
      console.log(item.text);
    });
  }
);
通らない例
$.getJSON('http://search.twitter.com/search.json',
  {
    callback: "?",
    q: "#jquery"
  },
  function(data, status){
    $.each(data.results, function(i, item){
      console.log(item.text);
    });
  }
);

*1:JSONPに対応しているAPIならという意味。

*2:追記:コメントでも触れたけど、Flickrはjsoncallback=fooだったりします。callbackってところが多いけど、違うのにしてるAPIもある感じ。

*3:紛らわしいけど、JSONPの callback=? とは別の、jQuery.getJSON()の第3引数のコールバック関数

tkuntkun 2012/05/11 00:59 callback=?
でgetjsonするとIEでスクリプトエラー出ませんか?
callback=foo
とかやれば出ないですが。

kanonjikanonji 2012/05/12 14:48 コメントどうもです。
改めて試しては無いですけど、エラーにはならないと思いますよ。

http://api.jquery.com/jQuery.getJSON/ のJSONPという見出しのところに

If the URL includes the string "callback=?" (or similar, as defined by the server-side API), the request is treated as JSONP instead. See the discussion of the jsonp data type in $.ajax() for more details.

と書いてあります。
このエントリーは、自分が他の解説を読んで、?には自分で関数名を入れるのかなという勘違いをしちゃったので書いたので、何か特別な事をしてるわけじゃなくって、jQueryの使い方そのままです。
なので、もしエラーになるとするなら、jQueryのバグか、何かが間違っているんじゃないかと思います。

ちなみに、callback=fooとして、jQuery.getJSON()の第1引数の文字列に ? が入ってない場合、jQuery.getJSON()はJSONPではなくJSONとしてxmlHttpRequestをするので、Same-Domainの制限を受けて、外部サイトのAPIとは通信できないんじゃないかと思います。

あと、自分のエントリー読み直してちょっと分かりにくいところがありました。
callback=?のcalllbackですが、これはTwitterとかJSONPのAPIを提供しているところが、大抵callback使っているというだけで、外部APIによっては別の名前がありえます。
例えばFlickrはcallbackじゃなくてjsoncallbackだったりします。

zedszeds 2012/07/29 04:39 YOLPのAPI叩いていて、callback: "?"でできず悩んでいたらこのページを見つけて解決しました!
ありがとうございます!

kanonjikanonji 2012/07/29 17:16 コメントどもです。
分かってしまえばなんてこと無いんですが、最初調べてる時は、ちょっと誤解しやすいんですよね。
お役に立ったようでよかったです。

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証