Подтвердить что ты не робот

Как вызвать функцию на 404 в JSON-ajax-запросе с помощью jQuery?

Я хочу сделать запрос Ajax с ответом в JSON. Поэтому я сделал этот запрос Ajax:

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },
    complete: function(data) {
      alert('complete')
    }})

Этот код работает хорошо, но когда мой url посылает мне HTTP-код 404, обратные вызовы не используются, даже полный обратный вызов. После исследования это потому, что мой dataType - это "json", поэтому возврат 404 - это HTML, а сеанс JSON не прошел. Таким образом, нет обратного вызова.

У вас есть решение для вызова функции обратного вызова при поднятии 404?

РЕДАКТИРОВАТЬ: полный обратный вызов не вызывает - это возврат 404. Если вы хотите URL-адрес 404, вы можете позвонить: http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697 it с этим URL-адресом у меня есть моя проблема.

4b9b3361

Ответ 1

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: "json",
    success: function(data) {
        alert('success');
    },
    error: function(data) {
        alert('error');
    },
    complete: function(xhr, data) {
        if (xhr.status != 0)
             alert('success');
        else
             alert('fail');
    }
})

Ответ 2

В вашей конфигурации jQuery использует jsonp для переноса данных. Это работает путем динамической вставки элемента script и установки URL-адреса для указанного значения. Затем данные, возвращаемые сервером, оцениваются как JavaScript - обычно вызывается предоставленный обратный вызов. Если сервер возвращает 404, содержимое, очевидно, не содержит JavaScript, и обратный вызов никогда не вызывается. Некоторые браузеры поддерживают обработчики ошибок в теге script, которые вызываются в этих ситуациях. К сожалению, IE не поддерживает это. Лучший способ обнаружить ошибку - полагаться на таймаут.

В вашем случае вы должны указать дополнительную опцию timeout, которая вызывает вызов обработчика ошибок, если вызов не был вызван вовремя (что было бы в случае ответа 404).

$.ajax({
  url: 'http://my_url',
  timeout: 2000, // 2 seconds timeout
  dataType: "json",
  success: function(data){
    alert('success');
  },
  error: function(data){
    alert('error');
  },
  complete: function(data) {
    alert('complete')
  }
});

Ответ 3

Если вы хотите обрабатывать ошибки при обращении к API Twitter с помощью Javascript и jsonp, вам нужно включить параметр suppress_response_codes в свой запрос. Это заставляет все ответы от API Twitter отвечать с ответом 200 OK и включать в себя ошибку. Затем вам нужно проверить, включает ли ответ параметр error или нет.

$.ajax({
  url: "https://api.twitter.com/1/users/show.json",
  dataType: 'jsonp',
  jsonp: "callback",
  data: {
    screen_name: "simongate1337",
    suppress_response_codes: true // <- Important part
  },
  success: function(data) {
    if(data.error) {
      console.log("ERROR: "+data.error);
    } else {
      console.log("Success, got user " + data.screen_name);
    }
  }
});

Ответ 4

Используйте statusCode -Option

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    statusCode: {
        404:function(){
            alert("I could not find the informations you requested.");
        }
    } 
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },
    complete: function(data) {
      alert('complete')
    }})

Ответ 5

Не думаете ли вы, что проблема связана не с типом dataType, а с запросами на междоменное соединение, которые вам не разрешено делать?

Приведенный ниже код работает, как ожидается, когда вы запрашиваете данные из того же домена и не выполняете кросс-доменные запросы:

function handle404(xhr){
    alert('404 not found');
}

function handleError(xhr, status, exc) {
     // 0 for cross-domain requests in FF and security exception in IE 
    alert(xhr.status);
    switch (xhr.status) {
        case 404:
            handle404(xhr);
            break;
    }
}

function dumbRequest() {
    var url = 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697';
    url = 'http://twitter.com/';    
    url = '/mydata.json';    
//    url = 'mydata.json';    
    $.ajax(
        {url: url,
         dataType: 'json',
         error: handleError}
    );
}

Ответ 6

Это просто потому, что для параметра dataType установлено значение "json"? Если да, попробуйте изменить его на text и сами оцените JSON:

$.ajax({
    url: 'http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697',
    dataType: 'text',
    success: function(data, status, xmlHttp) {
        try {
            data = eval('(' + data + ')');
            alert('success');
        } catch (e) {
            alert('json parse error');
        }
    },
    error: function(xmlHttp, status, error) {
        alert('error');
    },
    complete: function(xmlHttp, status) {
        alert('complete');
    }
});

Ответ 7

Знаете ли вы, что, хотя статус HTTP равен 404, фактическое тело действительно JSON? Например, эта ссылка имеет следующий JSON:

jsonp1269278524295({"request":"/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697","error":"Not found"})

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

UPDATE: по-видимому, хотя фактическое содержимое страницы действительно JSON, браузер (я проверил в Firefox) не выполняет его, скорее всего, потому что это 404. Поскольку jQuery имеет для добавления элемента script (из-за проблемы с междоменью) его оболочка JSONP никогда не вызывается, и, как следствие, ни один из ваших обратных вызовов.

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

Ответ 8

Просто столкнулся с той же проблемой и увидел еще один вопрос, который упоминал, что jQuery-JSONP (jQuery Плагин) поддерживает обнаружение ошибок 404 или, как они описывают: "восстановление ошибок в случае сбоя сети или плохо сформированных ответов JSON"

И он отлично работает:)

Вот мой (упрощенный) код для получения сведений о видео YouTube через JSONP:

$.jsonp(
{
    url: "https://gdata.youtube.com/feeds/api/videos/ee925OTFBCA",
    callbackParameter: "callback",
    data: 
    {
        alt: "jsonc-in-script",
        v: "2"
    },
    success: function(json, textStatus) 
    { 
        console.log("WEEEEEEEE!"); 
    },
    error: function(xOptions, textStatus) 
    {
        console.error(arguments);
    }
});

Ответ 9

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

Мой первоначальный вызов:

  $.ajax({ type: 'POST', 
    url: '../doSomething',
    data: 'my data',
    success: function(data) {
      if (HasErrors(data)) return;
      var info = eval('(' + data + ')');
      // do what you want with the info object
    },
    error: function(xmlHttpRequest) {
      ReportFailure(xmlHttpRequest);
    }
  });

И две вспомогательные функции:

function HasErrors(data) {
  if (data.search(/login\.aspx/i) != -1) {
    // timed out and being redirected to login page!
    top.location.href = '../login.aspx';
    return true;
  }
  if (data.search(/Internal Server Error/) != -1) {
    ShowStatusFailed('Server Error.');
    return true;
  }
  if (data.search(/Error.aspx/) != -1) {
    // being redirected to site error reporting page...
    ShowStatusFailed('Server Error. Please try again.');
    return true;
  }
  return false;
}

и

function ReportFailure(msg) {
  var text;
  if (typeof msg == 'string') {
    text = msg;
  }
  else if (typeof msg.statusText == 'string') {
    if (msg.status == 200) {
      text = msg.responseText;
    }
    else {
      text = '(' + msg.status + ') ' + msg.statusText + ': ';
      // use the Title from the error response if possible
      var matches = msg.responseText.match(/\<title\>(.*?)\<\/title\>/i);
      if (matches != null)
      { text = text + matches[1]; }
      else
      { text = text + msg.responseText; }
    }
  }
  // do something in your page to show the "text" error message
  $('#statusDisplay')
    .html('<span class="ui-icon ui-icon-alert"></span>' + text)
    .addClass('StatusError');
}

Ответ 10

Следующее решение работает отлично для меня:)

$.ajax({
    url: 'http://my_url',
    dataType: "json",
    success: function(data){
      alert('success');
    },
    error: function(data){
      alert('error');
    },complete: function(xhr, data) {
        if(data==="parsererror"){
             alert('404');
        }
    } 
});