Как поймать jQuery $.getJSON (или $.Аякс с Тип данных значение 'JSONP в') ошибка при использовании JSONP в?

можно ли поймать ошибку при использовании 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 ответов


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

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


здесьмой обширный ответ на подобный вопрос.

вот код:

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

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

As thedawnrider упоминается в комментариях, вы также можете использовать 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 секунд, если ваш флаг все еще не установлен, время ожидания запроса истекло.


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

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

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

надеюсь, что это помогает :)


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

?обратного вызова=?&ошибка=?

Это называется JSONPE, но это совсем не стандарт defacto.

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

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


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

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

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

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

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

alert("Error : " + err);

Mayby это работает?

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

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


вы ca явно обрабатываете любой номер ошибки, добавляя этот атрибут в запрос 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");
}
});

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


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

однако вы можете добавить переменные состояния и 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");
    }         
});

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

надеюсь, это поможет кому-то еще искать ответ на этот вопрос.