jQuery と JSONP で Bing の画像検索を利用してみる
Bing のレスポンスで「invalid label」というエラーが発生した原因
Bing のレスポンスで「invalid label」というエラーが発生した原因は、Bing で JSONP として処理をするには、「JsonType」と「JsonCallback」をリクエスト時に設定していなかったことが原因。これをリクエスト時に設定すれば、「invalid label」のエラーは発生しない。
「JsonType」には JavaScript で処理するために、「callback」値を設定する。「JsonCallback」には callback の関数名を設定する。
id:sshi さんにコメントで、JSON では数値を「"」で囲まなくていい仕様と指摘されていた。自分の勘違いに気がついたのは午前 2時過ぎだったので、今になってやっと訂正…。
console.log() で値を確認するために、FireFox + FireBug が必要。
サンプルコード
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <script type="text/javascript" src="js/jquery-1.4.1.min.js"></script> <script type="text/javascript"> $(function() { var query = 'ソメイヨシノ'; searchImagesWithBing(query); }); function searchImagesWithBing(query) { // JSON で検索結果を取得するための問い合わせ先 URL var url = 'http://api.search.live.net/json.aspx'; var appid = 'Enter Your App ID'; var source = 'image'; var count = '10'; var offset = '0'; var version = '2.2'; // 検索結果を JSON 形式で取得し JSONP として処理するための設定値 var jsontype = 'callback'; $.ajax({ dataType: 'jsonp', data: { Appid: appid, Query: query, Sources: source, 'Image.Count': count, 'Image.Offset': offset, Version: version, JsonType: jsontype }, cache: true, // Bing API で指定する callback のパラメーター「名」 // パラメーター「値」ではないことに注意 jsonp: 'JsonCallback', //url: 'http://api.search.live.net/json.aspx?&JsonCallback=?&', url: url, error: function(response) { console.log(response); console.log('Response Error.'); }, success: function (response) { var errors = response.SearchResponse.Errors; if (errors != null) { console.log('Request Error.'); console.log(errors); } else { var imgElement = null; var aElement = null; var title = null; var img_medium = null; var html_medium = null; var img_small = null; var width_small = 0; var height_small = 0; var results = response.SearchResponse.Image.Results; for (var i = 0; i < results.length; i ++) { title = results[i]['Title']; img_medium = results[i]['MediaUrl']; html_medium = results[i]['Url']; img_small = results[i]['Thumbnail']['Url']; width_small = results[i]['Thumbnail']['Width']; height_small = results[i]['Thumbnail']['Height']; imgElement = '<img src="' + img_small + '" width="' + width_small + '" height="' + height_small + '" alt="' + title + '" />'; aElement = '<a href="' + img_medium + '">' + imgElement + '</a>'; $('<div class="image"></div>').append(aElement).appendTo('body'); } } } }); } </script> <title>Bing Image</title> </head> <body> </body> </html>
jQuery と JSONP と $.ajax() と無名関数
JavaScript のコードをほとんど書いたことがなく、jQuery も JSONP も初めてだったので、戸惑うことが多かった。
Bing で callback で利用する関数を指定するパラメーター名は JsonCallback
Bing のように callback 関数を明示的に指定する必要がある場合は、
$.ajax({ url: 'http://localhost/ajax', dataType: 'jsonp', query: 'hoge', type: 'fuga', data: { ... }, jsonp: 'JsonCallback', // jsonp: に callback 関数を指定するパラメータ名を設定する error: function({ ... }), success: function({ ... }), completed: function({ ... }) });
のように「jsonp:」にパラメータ名を指定する必要があることが最初わからなかった。
「jsonp:」が指定されない場合
jQuery で AJAX を利用するサンプルコードで「jsonp:」に値が設定されていないものを見かけるが、「jsonp:」が設定されていない場合、callback 関数を指定するパラメータ名は、callback が指定される(ややこしい)。
どういうことかというと、例えば「jsonp: JsonCallback」でパラメータ名を明示している場合は、
http://localhost/ajax?query=hoge&type=fuga&JsonCallback=callbackの関数名
となる。では、「jsonp:」でパラメータ名が指定されていない場合は、
http://localhost/ajax?query=hoge&type=fuga&callback=callbackの関数名
というように、「callback」がデフォルトで設定されているようになっている。そのため、Yahoo WEB API のように明示しなくても、JSONP での処理ができる。
だからこそかもしれないが、Bing のように callback のパラメータ名ではない場合、初心者は戸惑うように思う。
callback を指定するパラメータ名とパラメータ値としての「?」
これを調べている際に、「jsonp:」を明示しないで JSONP を処理するための方法を示しているページをいくつか見つけた。
その方法は、
$.ajax({ // callback 関数を指定するパラメータ名の値に「?」を指定する URL を // 「url:」に指定する url: 'http://localhost/ajax?JsonCallback=?&', dataType: 'jsonp', query: 'hoge', type: 'fuga', data: { ... }, error: function({ ... }), success: function({ ... }), completed: function({ ... }) });
callback 関数を指定するパラメータ名の値に「?」を指定する方法だった。こうすることで、上記と同様に「?」が無名関数に置換されてサーバーにリクエストが送られている。
http://localhost/ajax?JsonCallback=callbackの関数名&query=hoge&type=fuga&
ここまで理解するのに、ほぼ丸一日を費やした…。