Проблема Angularjs $http.get не работает
Я новичок в Angularjs и попытался следовать примеру, приведенному для $http.get, на документации сайта angularjs.
У меня есть служба REST, которая при вызове возвращает данные следующим образом:
http://abc.com:8080/Files/REST/v1/list?&filter=FILE
{
"files": [
{
"filename": "a.json",
"type": "json",
"uploaded_ts": "20130321"
},
{
"filename": "b.xml",
"type": "xml",
"uploaded_ts": "20130321"
}
],
"num_files": 2}
Часть содержимого моего файла index.html выглядит следующим образом:
<div class="span6" ng-controller="FetchCtrl">
<form class="form-horizontal">
<button class="btn btn-success btn-large" ng-click="fetch()">Search</button>
</form>
<h2>File Names</h2>
<pre>http status code: {{status}}</pre>
<div ng-repeat="file in data.files">
<pre>Filename: {{file.filename}}</pre>
</div>
И мой js файл выглядит следующим образом:
function FetchCtrl($scope, $http, $templateCache) {
$scope.method = 'GET'; $scope.url = 'http://abc.com:8080/Files/REST/v1/list?&filter=FILE';
$scope.fetch = function() {
$scope.code = null;
$scope.response = null;
$http({method: $scope.method, url: $scope.url, cache: $templateCache}).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
}).
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
};
}
Но когда я запускаю это, я не вижу никакого результата для имен файлов, и я вижу код http status = 0
Когда я запускаю,
http://abc.com:8080/Files/REST/v1/list?&filter=FILE
в браузере, я все еще вижу желаемые результаты (как упоминалось выше)
Я даже пытался отлаживать Firebug в firefox, я вижу, что указанный выше URL-адрес вызывается, когда я нажимаю кнопку "Поиск", но ответ выглядит пустым. И интересно в Firebug по URL, он показывает
OPTIONS "Above URL"
вместо
GET "Above URL"
Не могли бы вы сообщить мне, что я делаю неправильно и почему я не могу получить доступ к данным JSON?
Спасибо,
Ответы
Ответ 1
Это связано с тем, что angular обрабатывает запросы CORS (HTTP-запросы кросс-сайта). angular по умолчанию добавляет некоторые дополнительные заголовки HTTP, поэтому вы видите OPTIONS
запрос вместо GET
. Попробуйте удалить заголовок X-Requested-With
HTTP, добавив эту строку кода:
delete $http.defaults.headers.common['X-Requested-With'];
Что касается CORS, то упоминается в Mozilla Developer Network:
Стандарт совместного использования ресурсов Cross-Origin работает, добавляя новый HTTP-протокол которые позволяют серверам описывать набор истоков, которые разрешено читать эту информацию с помощью веб-браузера.
Ответ 2
У меня возникла проблема с использованием $resource, который также использует $http.
Я заметил, что когда я использовал AngularJS 1.0.6, запрос даже не появлялся в Firebug, но при использовании AngularJS 1.1.4 Firebug отображал бы запрос GET и ответ 200 OK, а также правильные заголовки, но пустой ответ. Фактически, заголовки также показали, что данные возвращались, как показано заголовком Content-Length, имеющим правильную длину содержимого, и сравнивая это с плагином клиента REST, который я использовал, который успешно извлекал данные.
После еще большего подозрения я решил попробовать другой браузер. Я изначально использовал Firefox 16.0.1 (а также попытался 20.0.1), но когда я попробовал IE 9 (и AngularJS 1.1.4), код работал корректно без каких-либо проблем.
Надеюсь, это поможет вам найти обходной путь. В моем случае я заметил, что у меня никогда не было этой проблемы с относительными URL-адресами, поэтому я меняю свое приложение так, чтобы и приложение, и API обслуживались в одном и том же порту. Это потенциально может быть ошибкой AngularJS.
Ответ 3
У меня была такая же проблема сегодня с firefox. IE работал нормально. Сначала я не думал, что это был корс, потому что, как и вы, у меня не было ошибок в консоли и получил статус 0 в моем методе ошибок в angular. В консоли firefox я получал ответ 200 в своих заголовках и длину содержимого, но не было реального ответа. Firefox использовал для предупреждения о межсайтовых скриптах, которые указывали бы вам в правильном направлении.
Я решил проблему, установив cors на моем api. Это действительно лучший способ пойти.
Если вы используете GET только с помощью api, вы также можете попробовать использовать jsonp, который строится прямо в angular, и это работает для корсов, когда вы не контролируете api, который вы потребляете.
$http.jsonp('http://yourapi.com/someurl')
.success(function (data, status, headers, config) {
alert("Hooray!");
})
.error(function (data, status, headers, config) {
alert("Dang It!");
});
Ответ 4
Это защита от межсайтового скриптинга.
Попробуйте запустить google chrome с помощью --disbable-web-security (через командную строку).
Если это не работает, попробуйте поместить свой материал angular в http-сервер вместо использования файлового протокола. (Совет: используйте хром-канарейку, если вы хотите иметь браузер, предназначенный для --disable-web-security, - конечно, вам придется также задать аргумент командной строки, но обе версии хрома запускаются одновременно). Для выпуска вам нужно будет установить некоторые HTTP-заголовки на сервере, предоставляя материалы AngularJS, чтобы разрешить доступ к твиттеру api или тому, что вы хотите вызвать.