JqXHR - http-status-code-403 (но код состояния равен 0)

Я получаю код состояния 0... но это код 403. Может кто-нибудь сказать мне, в чем проблема?

JQuery

  var jqxhr = $.ajax({
        url: 'http://gdata.youtube.com/feeds/api/users/bernd/favorites?alt=json',
        dataType: 'json'
    }).success(function(xhr) {
        alert(xhr.status);
    }).error(function(xhr) {
        alert(xhr.status);
        return false;
    })

DEMOhttp://jsfiddle.net/QFuBr/

Спасибо заранее!
Питер

Ответ 1

Сервер предоставляет ошибку 403 для браузера, поскольку у вас нет разрешения на доступ к ресурсу из-за сообщения об ошибке ( "Избранное запрошенного пользователя не являются общедоступными" ).

Однако на сервере не даже получить запрос в примере jsFiddle.

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

Если вы даже не дошли до отправки запроса на сервер, кода статуса нет. Об этом сообщает объект XMLHTTPRequest (и его оболочка jqXHR) как 0.

В принципе, вы не можете делать то, что вы пытаетесь сделать в браузере.

Если вам нужен браузер для доступа к данным типа асинхронно, вам нужно написать обертку на своем сервере, чтобы получить информацию с удаленного сервера и отправить ее в браузер. Существует обходной путь (он называется JSONP – JSON с Padding) , но я не верю, что YouTube поддерживает его.


Изменить: на ответ gradbot, можно выполнить запрос JSONP, изменив код, чтобы установить dataType в jsonp.

Однако теперь вы не сможете использовать xhr.status. Это связано с тем, что JSONP не использует объект XHR, поэтому нет статуса, доступного для проверки.

Здесь показан рабочий пример с использованием предложенного метода feedbot. Обратите внимание, что объект результата передается обработчику, а не объект jqXHR.

Ответ 2

Вам нужно установить dataType: "jsonp", и вам нужно войти в систему как пользователь, с которого вы пытаетесь получить избранное. В этом случае я использую собственное имя пользователя grabot, и предупреждение возвращается с успехом.

Если у вас нет действительного файла cookie для вашей учетной записи, пытающегося получить доступ, тогда вызов api вернет 403 с контентом "Favorites of requested user are not public."

$(function() {
    var jqxhr = $.ajax({
        url: 'http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json',
        dataType: 'jsonp'
    }).success(function(data, status) {
        alert(status);
    }).error(function(xhr) {
        alert(xhr.status);
    })
});

Ответ 3

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

В большинстве случаев код состояния 0 подразумевает, что запрос не может быть отправлен на сервер. Вот то, что журналы консоли Chrome показывают для вашего примера скрипта.

XMLHttpRequest не может загрузить http://gdata.youtube.com/feeds/api/users/bernd/favorites?alt=json. Происхождение http://fiddle.jshell.net не разрешено Access-Control-Allow-Origin.

Youtube, фактически поддержка всех API данных Google JSONP, но для его использования вы должны передать параметр alt со значением json-in-script и указать dataType как jsonp. jQuery предоставит вам параметр обратного вызова. Основываясь на эмпирическом тестировании, кажется, что Youtube не заботится о параметре alt, который будет конкретно json-in-script. Пока указан параметр callback, параметр alt может принимать только значение json.

http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json http://gdata.youtube.com/feeds/api/users/gradbot/favorites?alt=json&callback=foo

Здесь рабочий пример для общедоступного фида.

$.ajax({
    url: 'http://gdata.youtube.com/feeds/mobile/videos?alt=json-in-script',
    dataType: 'jsonp',
    success: function(data) {
        // do something with data
    }
});

Ответ 4

Вы не можете выполнять междоменные запросы (будь то GET или POST) из-за ограничений безопасности в большинстве современных браузеров.

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

Один из самых популярных - mod_reverse в Apache, но есть и другие альтернативы в зависимости от того, что такое серверная среда.

Другим вариантом является пользователь JSONP, если Google API поддерживает его.