$ http.get не разрешен Access-Control-Allow-Origin, но $.ajax is
У меня проблема с выбором json с удаленного сервера, который я контролирую. У меня есть 2 веб-приложения, один обслуживающий данные и работающий на порту 3311, другой, запрашивающий данные, работает на порту 5000.
используя jquery следующие работы:
$.ajax({
url: "http://localhost:3311/get-data",
type: 'GET',
dataType: 'json',
beforeSend: function(xhr) {
xhr.setRequestHeader("x-some-header", "some-value");
}
})
.done(function(data) {
$rootScope.$apply(function() {d.resolve(data); });
})
.fail(function(data) {
$rootScope.$apply(function() {d.reject(data); });
});
при попытке получить тот же запрос на получение с angular
$http
.get("http://localhost:3311/get-data", { headers: {"x-some-header": "some-value"} })
.success(function(data) { d.resolve(data);})
.error(function(data) { d.reject(data); });
Я получаю сообщение об ошибке
Origin http://localhost:5000 is not allowed by Access-Control-Allow-Origin.
В журнале консоли отображается ошибка, возникающая после запроса OPTIONS HTTP200
OPTIONS http://localhost:3311//get-data 200 (OK) angular.min.js:99
(anonymous function) angular.min.js:99
l angular.min.js:95
m angular.min.js:94
(anonymous function) app.js:78
b.extend.each jquery-1.9.1.min.js:3
b.fn.b.each jquery-1.9.1.min.js:3
(anonymous function) app.js:76
d angular.min.js:28
instantiate angular.min.js:28
(anonymous function) angular.min.js:52
updateView angular-ui-states.js:892
e.$broadcast angular.min.js:90
transition angular-ui-states.js:324
h angular.min.js:77
(anonymous function) angular.min.js:78
e.$eval angular.min.js:88
e.$digest angular.min.js:86
e.$apply angular.min.js:88
e angular.min.js:94
o angular.min.js:98
s.onreadystatechange angular.min.js:99
а заголовки, возвращаемые из запроса OPTIONS,
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/plain
Server: Microsoft-IIS/8.0
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With, x-some-header
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?....
X-Powered-By: ASP.NET
Date: Tue, 21 May 2013 01:52:37 GMT
Content-Length: 0
Ответы
Ответ 1
Вероятно, это связано с поведением Angular по умолчанию для включения заголовка запроса 'X-Requested-With'
, что может вызвать проблемы с CORS. Это было исправлено в версии 1.1.1 (неустойчивая ветка - см. Исправления ошибок v1.1.1), удалив заголовок из междоменных запросов: https://github.com/angular/angular.js/issues/1004.
Легко удалить заголовок и заставить его работать с ветвью 1.0. Следующая строка удалит заголовок из всех запросов (не только CORS), выполненных службой $http в вашем приложении:
yourModule
.config(function($httpProvider){
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
Обновление
Небольшое предупреждение - Angular (например, jQuery) не поддерживает CORS для IE9. IE10 - это первый браузер IE, поддерживающий CORS. Этот блогпост описывает, как вы можете получить поддержку CORS в IE8/IE9 при определенных условиях, но она не будет работать с сервисом Angular $http: http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx
Ответ 2
web.config
<system.webServer>
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
</system.webServer>
Ответ 3
Ответ выше решил проблему.
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
</customHeaders>
</httpProtocol>
Когда страница HTML вызывала контроллер angular с сервисом вроде:
$http.get(dataUrl).success(function (data) {
$scope.data.products = data;
})
.error(function (error) {
$scope.data.error = error;
});
Ответ 4
Запрошенные заголовки должны быть установлены на стороне сервера.
Существует много способов установить этот
1. Может быть
<filter>
<filter-name>ResponseFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ResponseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2. Независимо от сервера, вы можете разработать пользовательский класс, который может быть передан как init-параметр для трикотажа сервлета com.sun.jersey.spi.container.ContainerResponseFilters helpers.TestCorpsFilter enter code here
`public class TestCorpsFilter реализует ContainerResponseFilter {
@Override
public ContainerResponse filter(ContainerRequest arg0, ContainerResponse arg1) {
ResponseBuilder resp = Response.fromResponse(arg1.getResponse());
resp.header("Access-Control-Allow-Origin", "*").header("Access-Control-Allow-Methods",
"GET, POST, OPTIONS");
String requestHeader = arg0.getHeaderValue("Access-Control-Request-Headers");
if (requestHeader != null && !requestHeader.equals("")) {
resp.header("Access-Control-Allow-Headers", requestHeader);
}
arg1.setResponse(resp.build());
return arg1;
}