Как к обратному вызову функция на 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, никакие обратные вызовы не используются, даже полный обратный вызов. После исследования это - потому что мой тип данных является 'json', таким образом, 404 возвратами является HTML и неудавшийся парсинг JSON. Так никакой обратный вызов.

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

Править: полный обратный вызов не звонит, возврат, 404. Если Вы хотите остроумие URL 404, можно звонить: http://twitter.com/status/user_timeline/jksqdlmjmsd.json?count=3&callback=jsonp1269278524295&_=1269278536697, который это с этим URL, у меня есть своя проблема.

21
задан jao 17 August 2012 в 22:00
поделиться

6 ответов

$.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');
    }
})
19
ответ дан 29 November 2019 в 20:39
поделиться

Это просто потому, что для dataType установлено значение «json»? Если да, попробуйте изменить его на текст и самостоятельно оцените 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');
    }
});
1
ответ дан 29 November 2019 в 20:39
поделиться

В вашей конфигурации 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')
  }
});
9
ответ дан 29 November 2019 в 20:39
поделиться

Не считаете ли вы, что проблема не в 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}
    );
}
2
ответ дан 29 November 2019 в 20:39
поделиться

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

jsonp1269278524295 ({"request": "/ status / user_timeline / jksqdlmjmsd.json? Count = 3 & callback = jsonp1269278524295 & _ = 1269278536697", "error": " Не найдено "})

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

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

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

1
ответ дан 29 November 2019 в 20:39
поделиться

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

Мой первый вызов:

  $.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');
}
0
ответ дан 29 November 2019 в 20:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: