Как отловить ошибку jQuery $ .getJSON (или $ .ajax с типом данных 'jsonp') при использовании JSONP? - PullRequest
75 голосов
/ 21 ноября 2008

Можно ли перехватить ошибку при использовании JSONP с jQuery? Я пробовал оба метода $ .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");
});

Заранее спасибо за любые ответы!

Ответы [ 10 ]

52 голосов
/ 29 сентября 2013

Здесь - мой исчерпывающий ответ на подобный вопрос.

Вот код:

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!'); });
51 голосов
/ 21 ноября 2008

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

После поиска по их баг-трекеру, есть патч , который может быть возможным решением с использованием обратного вызова тайм-аута. См. отчет об ошибке # 3442 . Если вы не можете зафиксировать ошибку, вы можете по крайней мере тайм-аут после ожидания разумного количества времени для успеха.

15 голосов
/ 03 августа 2012

Обнаружение проблем 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);

Как упоминалось в комментариях рассвета, вместо него можно использовать 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 не использует XMLHttpRequest, как обычные запросы AJAX. Вместо этого он вставляет тег <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 секунд, если ваш флаг все еще не был установлен, время запроса истекло.

14 голосов
/ 05 сентября 2013

Я знаю, что этот вопрос немного старый, но я не видел ответа, который бы дал простое решение проблемы, поэтому я решил поделиться своим «простым» решением.

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

Мы можем просто использовать обратный вызов .fail(), чтобы проверить, не произошла ли ошибка.

Надеюсь, это поможет:)

3 голосов
/ 06 июня 2010

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

? Обратного =? & Ошибка =?

Это называется JSONPE, но это не стандарт де-факто.

Затем поставщик передает информацию в функцию ошибок, чтобы помочь вам в диагностике.

Не помогает с ошибками связи - jQuery необходимо обновить, чтобы он также вызывал функцию ошибки по таймауту, как в ответе Адама Беллера.

2 голосов
/ 18 января 2010

Похоже, это работает сейчас:

jQuery(document).ajaxError(function(event, request, settings){
   alert("Error");
});
1 голос
/ 22 июня 2012

Я использую это, чтобы поймать ошибку JSON

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

Редактировать: В качестве альтернативы вы также можете получить сообщение об ошибке. Это даст вам знать, в чем именно заключается ошибка. Попробуйте следующий синтаксис в блоке catch

alert("Error : " + err);
0 голосов
/ 28 ноября 2013

Я также отправил этот ответ в стек переполнение - Обработка ошибок в вызовах 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 для предоставления ссылки на данные JSON, отправку данных в качестве места для добавления "?callback=?" и других переменных, которые необходимо отправить для получения правильных возвращаемых данных JSON, и функцию успеха в виде функция для обработки данных.

Однако вы можете добавить переменные status и xhr в вашу функцию успеха. Переменная состояния содержит одну из следующих строк: «success», «notmodified», «error», «timeout» или «parsererror», а переменная xhr содержит возвращенный объект XMLHttpRequest ( найдено в 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 голосов
/ 02 августа 2013

Вы можете явно обработать любой номер ошибки, добавив этот атрибут в запрос 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 голосов
/ 13 сентября 2012

Может, это работает?

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

Я не знаю, когда статус переходит в режим «ошибки». Но я проверил это с 404, и он ответил

...