Как запустить обратный вызов с ошибкой jquery.ajax () на основе ответа сервера, а не HTTP 500?

#javascript #ajax #spring #jquery

#javascript #ajax #весна #jquery

Вопрос:

Используя функцию 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

 }

});
  

У меня есть два вопроса, основанные на приведенном выше коде:

  1. Когда будет вызван обратный вызов jquery.ajax() error ??

  2. Что, если сервер ответит мне объектом json со строковым сообщением «Произошла ошибка«. Это означает, что запрос все еще успешно отправлен, но я получил ответ сервера {message: "There is an error"} .

Я думаю, что независимо от того, на какое строковое значение отвечает сервер, если клиент получил ответ сервера, обратный вызов jquery.ajax () success будет запущен в любом случае.

Я хотел бы спросить, если сервер специально возвращает мне объект JSON со строковым значением типа {message: 'There is an error'} , может ли сервер сделать что-нибудь, чтобы этот ответ мог быть обработан в обратном вызове jquery.ajax() error вместо success обратного вызова?

Ответ №1:

Обратный вызов с ошибкой будет выполнен, когда ответ от сервера будет не таким, какой вы ожидали. Так, например, в этих ситуациях это:

  • Получено 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
});
  

Комментарии:

1. Зачем определять HandleError в совершенно отдельном месте? Почему бы просто не определить его встроенным следующим образом: error: handleError = function(xhr, status){//handle server response here}

2. @dallin потому что это позволяет вам не дублировать код. Сервер может ответить кодом 200, который запускает обратный вызов «success». Или неправильный код, такой как 400, 404 или 500, вызовет обратный вызов с ошибкой. В обоих случаях вы, вероятно, захотите обработать ошибку централизованным способом.

3. @MichaelButler Я думаю, вы могли неправильно понять, что я предлагал. Я полагаю, вы можете определить функцию с именем HandleError непосредственно в свойстве error ( ошибка: HandleError = функция(xhr, status) ). Это позволяет вам по-прежнему вручную вызывать функцию и обрабатывать ошибку в централизованном расположении. Это позволило бы сохранить обработку ошибок непосредственно в вызове ajax, еще больше централизовав работу. Вот jsfiddle с упрощенным примером: jsfiddle.net/dhq01bLv

4. @dallin спасибо, не знал, что вы можете это сделать. ваше решение, так сказать, дало бы лучшее из обоих миров.

Ответ №2:

Мы предполагаем, что сервер отправляет 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.
})
  

Ответ №3:

Обратный вызов с ошибкой возникает, когда не удалось успешно выполнить Ajax туда и обратно, а не что-то, основанное на логике вашего сервера. Вы несете ответственность за проверку того, что вы считаете успешным ответом внутри успешного обратного вызова. т. Е. Добавьте одно условие IF, которое проверяет, соответствует ли сообщение = «Произошла ошибка». и включите туда свою логику ошибок, в противном случае выполните логику успеха.

Подход к выполнению того, что вы запрашиваете, заключался бы в том, чтобы сервер возвращал заголовок 404 при возникновении ошибки, тогда это было бы обработано обратным вызовом с ошибкой. Проблема с этим подходом заключается в том, что вы будете скрывать, есть ли фактические ошибки, и вы не сможете передать дополнительные данные с ним.

Комментарии:

1. Я понимаю, таким образом, нет способа вызвать обратный вызов с ошибкой на основе того, какой сервер ответил, верно?

2. @Leem Это просто функция… Мне трудно понять, почему вы хотите, чтобы это произошло, вместо того, чтобы проверять наличие ошибки в данных ответа. Однако я добавил метод взлома.

3. Я хотел бы посмотреть, есть ли возможность вызвать обратный вызов с ошибкой в моем случае, надеюсь, эта мотивация не доставит вам больше хлопот. Ответ Райелла проясняет ситуацию. Также спасибо.

Ответ №4:

Проще всего было бы реструктурировать следующим образом:

 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
});
  

Ответ №5:

Один из простых способов сделать это — просто использовать функцию jQuery always () для обратного вызова, а затем, если вы хотите вручную создать ошибку, просто воспользуйтесь утиным вводом!

Например:

 $.get(url, {"data": data}).always(function(result)
{
    if (typeof result.status !== "undefined" amp;amp; 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;
    }
}
  

Ответ №6:

Этот первоначальный вопрос был опубликован несколько лет назад, и, возможно, сейчас есть лучшие способы справиться с этим. Вот предложение для обработки нескольких типов ошибок, включая вопрос 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» (или что угодно еще, что вы хотите), чтобы вызвать ошибку; позволяет выполнять разные действия в зависимости от ошибки.