web-dev-qa-db-ja.com

JSONPを使用しているときにjQuery $ .getJSON(またはデータ型を 'jsonp'に設定した$ .ajax)エラーをキャッチするにはどうすればよいですか?

JQueryでJSONPを使用しているときにエラーをキャッチすることは可能ですか? $ .getJSONメソッドと$ .ajaxメソッドの両方を試しましたが、どちらもテスト中の404エラーをキャッチしません。私が試したことは次のとおりです(これらはすべて正常に機能しますが、失敗した場合は処理したいことに留意してください)。

jQuery.ajax({
    type: "GET",
    url: handlerURL,
    dataType: "jsonp",
    success: function(results){
        alert("Success!");
    },
    error: function(XMLHttpRequest, textStatus, errorThrown){
        alert("Error");
    }
});

そしてまた:

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    });

私も$ .ajaxErrorを追加しようとしましたが、それでもうまくいきませんでした:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});

返信ありがとうございます!

75
Andy May

成功した結果を返さないJSONPリクエストは、イベント(成功または失敗)をトリガーすることは決してないようです。

バグトラッカーを検索した後、 パッチ があります。これは、タイムアウトコールバックを使用した解決策の可能性があります。 バグレポート#3442 を参照してください。エラーをキャプチャできない場合は、成功するために妥当な時間待機した後、少なくともタイムアウトできます。

51
Adam Bellaire

こちら は、同様の質問に対する広範な回答です。

コードは次のとおりです。

jQuery.getJSON(handlerURL + "&callback=?", 
    function(jsonResult){
        alert("Success!");
    })
.done(function() { alert('getJSON request succeeded!'); })
.fail(function(jqXHR, textStatus, errorThrown) { alert('getJSON request failed! ' + textStatus); })
.always(function() { alert('getJSON request ended!'); });
52
user2314737

JSONP問題の検出

依存関係をダウンロードしたくない場合は、自分でエラー状態を検出できます。それは簡単です。

ある種のタイムアウトを使用することでのみJSONPエラーを検出できます。特定の時間内に有効な応答がない場合は、エラーと見なします。ただし、エラーは基本的に何でもかまいません。

エラーをチェックする簡単な方法を次に示します。 successフラグを使用するだけです:

var success = false;

$.getJSON(url, function(json) {
    success = true;
    // ... whatever else your callback needs to do ...
});

// Set a 5-second (or however long you want) timeout to check for errors
setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

コメントでdawnriderが言及したように、代わりにclearTimeoutを使用することもできます:

var errorTimeout = setTimeout(function() {
    if (!success)
    {
        // Handle error accordingly
        alert("Houston, we have a problem.");
    }
}, 5000);

$.getJSON(url, function(json) {
    clearTimeout(errorTimeout);
    // ... whatever else your callback needs to do ...
});

どうして?読む...


JSONPの概要は次のとおりです。

JSONPは、通常のAJAXリクエストのようなXMLHttpRequestを使用しません。代わりに、<script>タグをページに挿入します。「src」属性はリクエストのURLです。応答のコンテンツはJavascript関数でラップされ、ダウンロード時に実行されます。

たとえば

JSONPリクエスト:https://api.site.com/endpoint?this=that&callback=myFunc

JavascriptはこのスクリプトタグをDOMに挿入します。

<script src="https://api.site.com/endpoint?this=that&callback=myFunc"></script>

<script>タグがDOMに追加されますか?明らかに、実行されます。

したがって、このクエリに対する応答が次のようなJSON結果を生成したと仮定します。

{"answer":42}

ブラウザにとって、それはスクリプトのソースと同じことなので、実行されます。しかし、これを実行するとどうなりますか:

<script>{"answer":42}</script>

まあ、何も。それは単なるオブジェクトです。保存も保存もされず、何も起こりません。

JSONPリクエストが結果を関数でラップするのはこのためです。 JSONPシリアル化をサポートする必要があるサーバーは、指定したcallbackパラメーターを確認し、代わりにこれを返します。

myFunc({"answer":42})

次に、これは代わりに実行されます:

<script>myFunc({"answer":42})</script>

...これははるかに便利です。この場合、コードのどこかにmyFuncというグローバル関数があります。

myFunc(data)
{
    alert("The answer to life, the universe, and everything is: " + data.answer);
}

それでおしまい。それがJSONPの「魔法」です。タイムアウトチェックを組み込むのは、上記のように非常に簡単です。要求を行い、直後にタイムアウトを開始します。 X秒後、フラグがまだ設定されていない場合、リクエストはタイムアウトしました。

16
Matt

私はこの質問が少し古いことを知っていますが、問題の簡単な解決策を提供する答えが見つからなかったので、「簡単な」解決策を共有すると思いました。

_$.getJSON("example.json", function() {
      console.log( "success" );
}).fail(function() { 
      console.log( "error" ); 
}); 
_

.fail()コールバックを使用して、エラーが発生したかどうかを確認できます。

お役に立てれば :)

14
Farhan Ahmad

プロバイダーと協力する場合、エラーが発生したときにコールバックする関数である別のクエリ文字列パラメーターを送信できます。

?callback =?&error =?

これはJSONPEと呼ばれますが、事実上の標準ではありません。

その後、プロバイダーは診断に役立つ情報をエラー関数に渡します。

ただし、通信エラーには役立ちません-Adam Bellaireの答えのように、タイムアウト時にエラー関数もコールバックするためにjQueryを更新する必要があります。

3
delitescere

これは今働いているようです:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});
2
Fhansen

これを使用してJSONエラーをキャッチします

try {
   $.getJSON(ajaxURL,callback).ajaxError();
} catch(err) {
   alert("wow");
   alert("Error : "+ err);
}

編集:または、エラーメッセージを取得することもできます。これにより、エラーの内容が正確にわかります。 catchブロックで次の構文を試してください

alert("Error : " + err);
1
tomjshore

この属性をajaxリクエストに追加することにより、エラー番号を明示的に処理できます。

statusCode: {
        404: function() {
          alert("page not found");
        }
    }

したがって、コードは次のようになります。

jQuery.ajax({
type: "GET",
statusCode: {
        404: function() {
          alert("page not found");
        }
},
url: handlerURL,
dataType: "jsonp",
success: function(results){
    alert("Success!");
},
error: function(XMLHttpRequest, textStatus, errorThrown){
    alert("Error");
}
});

これがあなたを助けることを願っています:)

0
ghost rider3

たぶんこれは動作しますか?

.complete(function(response, status) {
    if (response.status == "404")
        alert("404 Error");
    else{
        //Do something
    }   
    if(status == "error")
        alert("Error");
    else{
        //Do something
    }
});

ステータスが「エラー」モードになるときはいつでもわかりません。しかし、私は404でそれをテストし、応答しました

0
Marcel

また、この回答を stackoverflow-getJSONコールでのエラー処理 に投稿しました

ここに誰かが答えてからポスターがすでにここか他のどこかからすでに答えを得ているので、それはしばらくしていたことを知っています。ただし、この投稿は、getJSONリクエストの実行中にエラーとタイムアウトを追跡する方法を探している人に役立つと思います。したがって、質問に対する私の答えの下

GetJSON構造は次のとおりです( http://api.jqueri.com にあります):

$(selector).getJSON(url,data,success(data,status,xhr))

ほとんどの人はそれを使用して実装します

$.getJSON(url, datatosend, function(data){
    //do something with the data
});

url varを使用してJSONデータへのリンクを提供します。datatoは、"?callback=?"および正しいJSONデータを取得するために送信する必要のある他の変数を追加する場所として送信し、成功関数はデータを処理するための関数。

ただし、成功関数にstatusおよびxhr変数を追加できます。ステータス変数には、「success」、「notmodified」、「error」、「timeout」、または「parsererror」の文字列のいずれかが含まれ、xhr変数には、返されたXMLHttpRequestオブジェクト( found on w3schools

$.getJSON(url, datatosend, function(data, status, xhr){
    if (status == "success"){
        //do something with the data
    }else if (status == "timeout"){
        alert("Something is wrong with the connection");
    }else if (status == "error" || status == "parsererror" ){
        alert("An error occured");
    }else{
        alert("datatosend did not change");
    }         
});

このように、リクエストが完了すると開始されるカスタムタイムアウトトラッカーを実装することなく、タイムアウトとエラーを簡単に追跡できます。

これが、この質問に対する答えをまだ探している人の助けになることを願っています。

0
Tom Groentjes