jQuery ajax(jsonp)はタイムアウトを無視し、エラーイベントを発生させません
-
05-07-2019 - |
質問
基本的なエラー処理を追加するために、jQueryの$ .getJSONを使用してFlickrから写真を取り込むコードを書き直したいと考えました。これを行う理由は、$。getJSONがエラー処理を提供しないか、タイムアウトを処理しないためです。
$。getJSONは$ .ajaxの単なるラッパーであるため、私はこのことを書き直してサプライズサプライズを行うことにしましたが、問題なく動作します。
今から楽しみが始まります。意図的に404を発生させる(URLを変更する)か、ネットワークをタイムアウトさせる(インターWebに接続されない)場合、エラーイベントはまったく発生しません。私が間違っていることについて私は途方に暮れています。ヘルプは大歓迎です。
コードは次のとおりです。
$(document).ready(function(){
// var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne"; // correct URL
var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne_______"; // this should throw a 404
$.ajax({
url: jsonFeed,
data: { "lang" : "en-us",
"format" : "json",
"tags" : "sunset"
},
dataType: "jsonp",
jsonp: "jsoncallback",
timeout: 5000,
success: function(data, status){
$.each(data.items, function(i,item){
$("<img>").attr("src", (item.media.m).replace("_m.","_s."))
.attr("alt", item.title)
.appendTo("ul#flickr")
.wrap("<li><a href=\"" + item.link + "\"></a></li>");
if (i == 9) return false;
});
},
error: function(XHR, textStatus, errorThrown){
alert("ERREUR: " + textStatus);
alert("ERREUR: " + errorThrown);
}
});
});
jQueryがバージョン1.4.2のときにこの質問が行われたことを追加したい
解決
jQuery 1.5以降では、JSONP要求によるエラー処理のサポートが向上しています。ただし、 $。getJSON
の代わりに $。ajax
メソッドを使用する必要があります。私にとって、これは機能します:
var req = $.ajax({
url : url,
dataType : "jsonp",
timeout : 10000
});
req.success(function() {
console.log('Yes! Success!');
});
req.error(function() {
console.log('Oh noes!');
});
10秒後にリクエストが成功しない場合、タイムアウトがトリックを実行し、エラーハンドラを呼び出すようです。
少しブログ投稿この件についても。
他のヒント
これは、jQueryのネイティブjsonp実装の既知の制限です。以下のテキストは、 IBM DeveloperWorks
JSONPは、 マッシュアップを作成しますが、残念ながら、 それはあなたのすべてのための万能薬ではありません クロスドメイン通信のニーズ。それ 取らなければならないいくつかの欠点があります 前に真剣に検討する 開発リソースをコミットします。 何よりもまず、エラーはありません JSONP呼び出しの処理。もし 動的なスクリプト挿入機能、あなた 呼ばれる;そうでなければ、何も起こりません。 黙って失敗するだけです。例えば、 404エラーをキャッチすることはできません サーバーから。キャンセルもできません 要求を再開します。ただし、できます 妥当な時間待機した後のタイムアウト 時間の長さ。 (将来のjQuery バージョンには、中止機能があります JSONPリクエスト。)
ただし、 GoogleCode にはエラーのサポートを提供するjsonpプラグインがあります。取り扱い。開始するには、コードに次の変更を加えるだけです。
ダウンロードするか、プラグインにスクリプト参照を追加するだけです。
<script type="text/javascript"
src="http://jquery-jsonp.googlecode.com/files/jquery.jsonp-1.0.4.min.js">
</script>
次に、以下に示すようにajax呼び出しを変更します。
$(function(){
//var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne"; // correct URL
var jsonFeed = "http://api.flickr.com/services/feeds/photos_public.gne_______"; // this should throw a 404
$.jsonp({
url: jsonFeed,
data: { "lang" : "en-us",
"format" : "json",
"tags" : "sunset"
},
dataType: "jsonp",
callbackParameter: "jsoncallback",
timeout: 5000,
success: function(data, status){
$.each(data.items, function(i,item){
$("<img>").attr("src", (item.media.m).replace("_m.","_s."))
.attr("alt", item.title)
.appendTo("ul#flickr")
.wrap("<li><a href=\"" + item.link + "\"></a></li>");
if (i == 9) return false;
});
},
error: function(XHR, textStatus, errorThrown){
alert("ERREUR: " + textStatus);
alert("ERREUR: " + errorThrown);
}
});
});
jQuery 1.4で立ち往生している場合の解決策:
var timeout = 10000;
var id = setTimeout( errorCallback, timeout );
$.ajax({
dataType: 'jsonp',
success: function() {
clearTimeout(id);
...
}
});
これは「既知」である可能性があります。 jQueryの制限;ただし、十分に文書化されていないようです。今日は約4時間を費やして、タイムアウトが機能しなかった理由を理解しました。
jquery.jsonp に切り替えたところ、魅力的に機能しました。ありがとう。
jQuery 1.5で解決されるようです。上記のコードを試してみたところ、コールバックが返ってきました。
「どうやら」と言う jQuery.ajax()のエラーコールバックのドキュメントには、まだ次の注意事項があるためです。
注:このハンドラーは、クロスドメインスクリプトおよびJSONPリクエストでは呼び出されません。
Jose Basilioの answer は GitHub にあります。 。
残念ながら、ドキュメントはやや質素なので、簡単な例を示しました:
$.jsonp({
cache: false,
url: "url",
callbackParameter: "callback",
data: { "key" : "value" },
success: function (json, textStatus, xOptions) {
// handle success - textStatus is "success"
},
error: function (xOptions, textStatus) {
// handle failure - textStatus is either "error" or "timeout"
}
});
重要 コール$ .jsonp()にcallbackParameterを含めます。そうしないと、コールバック関数がサービスコールのクエリ文字列に挿入されないことがわかりました(jquery-jsonpバージョン2.4.0以降)。
この質問は古いことは知っていますが、JSONPを使用したエラー処理の問題はまだ「解決」されていません。この質問が&quot; jquery jsonpエラー処理&quot;でGoogle内でトップランクにあるため、このアップデートが他のユーザーを支援することを願っています。
スクリプトのonerrorイベントをリッスンするのはどうですか? この問題が発生し、スクリプトタグが作成されたjqueryのメソッドにパッチを適用することで解決しました。興味深いコードを次に示します。
// Attach handlers for all browsers
script.onload = script.onreadystatechange = function( _, isAbort ) {
if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
cleanup();
// Callback if not abort
if ( !isAbort ) {
callback( 200, "success" );
}
}
};
/* ajax patch : */
script.onerror = function(){
cleanup();
// Sends an inappropriate error, still better than nothing
callback(404, "not found");
};
function cleanup(){
// Handle memory leak in IE
script.onload = script.onreadystatechange = null;
// Remove the script
if ( head && script.parentNode ) {
head.removeChild( script );
}
// Dereference the script
script = undefined;
}
このソリューションについてどう思いますか?互換性の問題を引き起こす可能性はありますか?