web-dev-qa-db-ja.com

HTTP 500ではなく、サーバー応答に基づいてjquery.ajax()エラーコールバックをトリガーする方法

Jquery ajax関数を使用すると、次のようなことができます。

$.ajax({

  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

 success: function(data) {

     //Handle server response here

  },

 error: function(xhr, status, error){

    //Handle failure here

 }

});

上記のコードに基づいて2つの質問をしました。

  1. Jquery.ajax()errorコールバックはいつ呼び出されますか?

  2. サーバーが文字列メッセージ「Error」を含むjsonオブジェクトに応答した場合はどうなりますか。つまり、リクエストは正常に送信されますが、サーバー応答{message: "There is an error"}を受け取りました。

サーバーがどの文字列値に応答しても、クライアントがサーバーの応答を取得した場合、jquery.ajax()successコールバックがとにかくトリガーされます。

サーバーが{message: 'There is an error'}のような文字列値を持つJSONオブジェクトを明確に返すかどうか、サーバーがこの応答をjquery.ajax()errorコールバックの代わりにsuccessコールバック?

40
Leem

エラーコールバックは、サーバーからの応答が期待したものにならないときに実行されます。したがって、たとえばこの状況では次のようになります。

  • HTTP 404/500またはその他のHTTPエラーメッセージが受信されました
  • 誤ったタイプのデータが受信されました(つまり、JSONを期待しているが、何か他のものを受信しました)。

あなたの状況では、データは正しいです(それはJSONメッセージです)。受信したデータの値に基づいてエラーコールバックを手動でトリガーする場合は、非常に簡単に行うことができます。エラーの匿名コールバックを名前付き関数に変更するだけです。

function handleError(xhr, status, error){

    //Handle failure here

 }

$.ajax({

  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

 success: function(data) {
     if (whatever) {
         handleError(xhr, status, ''); // manually trigger callback
     }
     //Handle server response here

  },

 error: handleError
});
31
RaYell

サーバーがJSONを送信していると仮定します。リクエストが成功した場合、次のようになります。

{
    success: true,
    data: {
        name: 'Foo'
    }
}

...および失敗時:

{
    success: false,
    error: 'Something bad happened.'
}

次に、 $。Deferred で応答をフィルタリングします。

$.get('http://localhost/api').then(function(res) {
    var filter = $.Deferred();

    if (res.success) {
        filter.resolve(res.data);
    } else {
        filter.reject(res.error);
    }

    return filter.promise();
}).done(function(data) {
    console.log('Name:',  data.name); // Outputs: Foo
}).fail(function(error) {
    console.log('Error:', error); // Outputs: Something bad happened.
})
26
Simen Brekken

エラーコールバックは、サーバーロジックに基づくものではなく、Ajaxラウンドトリップを正常に完了できなかった場合に使用します。成功のコールバック内で成功した応答とみなすものをチェックするのはあなたの責任です。つまり、メッセージが「エラーがありました」かどうかをチェックする単一のIF条件を追加します。エラーロジックをそこに含めます。そうでない場合は成功ロジックを実行します。

あなたが求めていることを行うアプローチは、エラーが発生したときにサーバーに404ヘッダーを返させ、エラーコールバックで処理することです。このアプローチの問題は、実際のエラーがある場合は隠れてしまい、追加のデータを渡すことができないことです。

3
Fosco

最も簡単なことは、次のように再構築することです。

function handleAjaxError function(xhr, status, error) {
    //Handle failure here
}

$.ajax({
  url: url,
  type: 'GET',
  async: true,
  dataType: 'json',
  data: data,

  success: function(data) {

     //Handle server response here
    if (data.message == 'There is an error')
    {
        handleAjaxError();
        return;
    }

    //... all is good....

  },
  error: handleAjaxError
});
2
Gary Green

この元の質問は数年前に投稿されたものであり、おそらくこれを処理するより良い方法があるでしょう。 複数の種類のエラーを処理するための提案があります(OPの質問を含む)。

入力タイプ(エラー)の例#1

function handleError (type){
type = type || "Connection Issue";
 var value = "Error occurred: " + type;
 alert(value);
}

function checkIfError(response){
    if (response == "DB_ERROR") {
        handleError("Server error");
        throw new Error("JS died"); // optional, keep from running additional script
     }
}

var example = {

    success: function (response) {
        checkIfError(response); // check data if error msg
        // do stuff when proper data sent
        alert(response);

    }, error: handleError // connection error, call error msg
};

test1 = example['error']();

入力タイプ(成功:エラー)の例#2

function handleError (type){
type = type || "Connection Issue";
 var value = "Error occurred: " + type;
 alert(value);
}

function checkIfError(response){
    if (response == "DB_ERROR") {
        handleError("Server error");
        throw new Error("JS died"); // optional, keep from running additional script
     }
}

var example = {

    success: function (response) {
        checkIfError(response); // check data if error msg
        // do stuff when proper data sent
        alert(response);

    }, error: handleError // connection error, call error msg
};


test2 = example['success']("DB_ERROR");

入力タイプ(成功)の例#3

function handleError (type){
type = type || "Connection Issue";
 var value = "Error occurred: " + type;
 alert(value);
}

function checkIfError(response){
    if (response == "DB_ERROR") {
        handleError("Server error");
        throw new Error("JS died"); // optional, keep from running additional script
     }
}

var example = {

    success: function (response) {
        checkIfError(response); // check data if error msg
        // do stuff when proper data sent
        alert(response);

    }, error: handleError // connection error, call error msg
};


test3 = example['success']("Proper Response");

関数を使用することにより、スクリプトで複数の呼び出しがある場合、変更を簡素化できます。

PHP(または任意のサーバー側コード)が"DB_ERROR"(または任意)の応答を返してエラーをトリガーします。さまざまなことを行うことができます。エラーに応じて。

0
Ben in CA

これを行う簡単な方法の1つは、コールバックにjQuery always()関数を使用し、それから手動でエラーを作成する場合は、Duck Typingを利用することです!

例えば:

$.get(url, {"data": data}).always(function(result)
{
    if (typeof result.status !== "undefined" && result.status !== 200) // Status code 200 represents Success/OK
    {
        //handle error
        error = "Your error was " + result.status + " " + result.statusText;
    }
    else
    {
        //success
    }
});

404 Not Foundなどの自然なヘッダーエラーがあった場合、エラーセクションは常に実行されます。手動でエラーを返したい場合、通常エラーで渡されるXHRオブジェクトをエミュレートすることができます(例:PHP):

public function ServerSideAjaxResponse($data)
{
    if (!$data)
    {
        $response["status"] = 1001; //Make up your own error codes! Yippee! Fun!
        $response["statusText"] = "Error! You forgot to send the data!";
        echo json_encode($return);
        return;
    }
}
0
dallin