Я хочу выполнить запрос 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, у меня есть своя проблема.
$.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');
}
})
Это просто потому, что для 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');
}
});
В вашей конфигурации 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')
}
});
Не считаете ли вы, что проблема не в 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}
);
}
Знаете ли вы, что, хотя статус HTTP равен 404, фактическое тело является действительным JSON? Например, эта ссылка содержит следующий JSON:
jsonp1269278524295 ({"request": "/ status / user_timeline / jksqdlmjmsd.json? Count = 3 & callback = jsonp1269278524295 & _ = 1269278536697", "error": " Не найдено "})
Таким образом, вы должны проверить, есть ли у ваших данных свойство error
в вашей обычной функции обратного вызова.
ОБНОВЛЕНИЕ : очевидно, хотя фактическое содержимое страницы является допустимым JSON, браузер (я проверял в Firefox) не выполняет его, скорее всего, потому что это 404. Поскольку jQuery должен добавить script
(из-за проблемы с междоменной обработкой), его оболочка JSONP никогда не вызывается, и, как следствие, ваши обратные вызовы тоже не выполняются.
Короче говоря, я не думаю, что есть способ справиться с этим без ручного добавления этого элемента скрипта и проверки того, вызывалась ли ваша предопределенная функция обратного вызова после этого.
Вот как я с этим справляюсь. Я проверяю возвращенные данные на наличие ошибок, прежде чем пытаться использовать их. То, что показано ниже, - это всего лишь образец, который вы можете расширить для более точного соответствия вашим требованиям. Также учитываются тайм-ауты сеанса и другие сценарии ...
Мой первый вызов:
$.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');
}