AngularJS / Alfresco / CORS过滤器问题:没有“Access-Control-Allow-Origin”头 [英] AngularJS / Alfresco / CORS filter issue: No 'Access-Control-Allow-Origin' header
问题描述
我遇到了 Alfresco(5.0.d),我的 AngularJS(1.4.3)客户端和 CORS 设置跨域/ No'Access-Control-Allow-Origin'标头存在于请求的资源问题)。
我从运行在localhost: 3000 上的AngularJS应用程序调用Alfresco REST API到在localhost上运行的Alfresco实例: 8080 (Tomcat,前面没有反向代理)。
这个XHR调用正常:
< blockquote>
这一个
http:// localhost:8080 / alfresco / service / api / login?u = admin& pw = admin
只能在Internet Explorer 11中使用,但在Chrome和Firefox 中,获取状态代码200返回0字节和在JS控制台中的错误:
XMLHttpRequest无法加载
http:// localhost:8080 / alfresco / service / api / login?u = admin& pw = admin 。在所请求的
资源上没有
'Access-Control-Allow-Origin'头。原因 http:// localhost:3000 因此不允许
访问。
在Alfresco web.xml中,我已启用CORS筛选器,如下所示:
<! - CORS过滤器映射开始 - >
< filter-mapping>
< filter-name> CORS< / filter-name>
< url-pattern> / api / *< / url-pattern>
< url-pattern> / service / *< / url-pattern>
< url-pattern> / s / *< / url-pattern>
< url-pattern> / cmisbrowser / *< / url-pattern>
< / filter-mapping>
<! - CORS Filter Mappings End - >
<! - CORS过滤器开始 - >
< filter>
< filter-name> CORS< / filter-name>
< filter-class> com.thetransactioncompany.cors.CORSFilter< / filter-class>
< init-param>
< param-name> cors.allowGenericHttpRequests< / param-name>
< param-value> true< / param-value>
< / init-param>
< init-param>
< param-name> cors.allowOrigin< / param-name>
<! - < param-value> http:// localhost:3000 http:// localhost:8081 http:// localhost:8080 https:// localhost< / param-value> - >
< param-value> *< / param-value>
< / init-param>
< init-param>
< param-name> cors.allowSubdomains< / param-name>
< param-value> true< / param-value>
< / init-param>
< init-param>
< param-name> cors.supportedMethods< / param-name>
< param-value> GET,HEAD,POST,PUT,DELETE,OPTIONS< / param-value>
< / init-param>
< init-param>
< param-name> cors.supportedHeaders< / param-name>
< param-value>原始,授权,x文件大小,x文件名,内容类型,接受,x文件类型< / param-value>
< / init-param>
< param-name> cors.supportsCredentials< / param-name>
< param-value> true< / param-value>
< / init-param>
< init-param>
< param-name> cors.maxAge< / param-name>
< param-value> 3600< / param-value>
< / init-param>
< / filter> - >
<! - CORS Filter End - >
来自Angular内的调用:
一个工作正常:
$ http.get('http:// localhost:8080 / alfresco / service / slingshot / live-search-docs?t = Project& alf_ticket = TICKET_9d9780c83b8b9525c7acb9d3d8da66c5c902fb76')。然后(function(response){
console.log('DATA LOADED:'+ response.items);
$ scope.contents = response.items;
});
回应标题:
HTTP / 1.1 200 OK
服务器:Apache-Coyote / 1.1
缓存控制:no-cache
到期日:Thu,01 Jan 1970 00:00:00 GMT
Pragma:no-cache
Content-Type:application / json; charset = UTF-8
Content-Length:85
Date:Thu,13 Aug 2015 06:37: 24 GMT
失败的
$ http.get('http:// localhost:8080 / alfresco / service / api / login?u ='+ $ scope.user.email +'& pw ='+ $ scope.user.password)。
then(function(response){
console.log('ALF_TICKET:'+ response.data.ticket);
$ scope.alfTicket = response.data.ticket;
$ state.go('admin-panel.default.introduction');
},function(response){
console.log('LOGIN FAILED');
});
回应标题:
HTTP / 1.1 200 OK
服务器:Apache-Coyote / 1.1
Access-Control-Allow-Credentials:true
访问控制允许原产地:http: / localhost:3000
Vary:Origin
Cache-Control:no-cache
Expires:Thu,01 Jan 1970 00:00:00 GMT
Pragma:no-cache
Content-Type:application / json; charset = UTF-8
Transfer-Encoding:chunked
Date:Thu,13 Aug 2015 06:38:36 GMT
我在AngularJS应用程序中配置了 $ httpProvider ,只是为了确保:
.config(['$ httpProvider',function($ httpProvider){
$ httpProvider.defaults.useXDomain = true;
delete $ httpProvider.defaults.headers.common ['X-Requested-With'];
}
从不同主机模拟的 CURL请求 工作正常,但有趣的是,我没有获得
Access-Control-Allow-Origin
不会。它必须与Alfresco config / webscript相关,但我还没有找到它的起源。
curl -H原始:http://www.baike.blogspot.com回复回复回复赞(0) //www.microsoft.com--verbosehttp://alfresco.mycompany.ch:8080/alfresco/service/api/login?u=admin&pw=12@echo
*在DNS缓存中找不到主机名
*尝试10.10.0.183 ...
*连接到alfresco.mycompany.ch(10.10.0.183)端口8080(#0)
> GET / alfresco / service / api / login?u = admin& pw = 12 @ echo HTTP / 1.1
> User-Agent:curl / 7.37.1
>主机:alfresco.mycompany.ch:8080
>接受:* / *
>原产地:http://www.microsoft.com
>
< HTTP / 1.1 200 OK
*服务器Apache-Coyote / 1.1未列入黑名单
<服务器:Apache-Coyote / 1.1
& Cache-Control:no-cache
<到期日:Thu,01 Jan 1970 00:00:00 GMT
< Pragma:no-cache
< Content-Type:application / json; charset = UTF-8
< Content-Length:85
<日期:星期四,13 8月2015 08:11:15 GMT
<
{
data:
{
ticket:TICKET_7d07634afbb25a7e823c0348d907e0790eeff97e
}
}
* Connection#0 to host alfresco .mycompany.ch left intact
因此我认为它是客户端/ AngularJS相关。
===更新1:===
我试图在$ httpProvider中添加拦截器如下,但它没有帮助。我没有看到任何响应中设置的标头,虽然拦截器被调用。
$ httpProvider。 interceptors.push(function(){
return {
'request':function(request){
return request;
},
'response':function响应){
console.log('Interceptor called。');
response.config.headers ['MyTestHeader'] ='12345';
response.config.headers ['Access- Control-Allow-Origin'] ='*';
return response;
}
};
}
=== Update 2:=== b
$ b更多的发现,但现在在Alfresco一边有点奇怪。我正在做两个几乎类似的API调用,到以下两个网址:
- http:// localhost:8080 / alfresco / service / api / login
- http:// localhost:8080 / alfresco / service / api / whatever
你可以看到,它们只是在结尾有所不同。具有
/ whatever
的响应头会返回Access-Control-Allow-Origin
响应头, c> / logincurl -H原产地:http://www.microsoft.com--verbosehttp:// localhost:8080 / alfresco / service / api / login
* Trying :: 1 ...
*连接到localhost(:: 1)端口8080(#0)
> GET / alfresco / service / api / login HTTP / 1.1
>主机:localhost:8080
> User-Agent:curl / 7.43.0
>接受:* / *
>原产地:http://www.microsoft.com
>
< HTTP / 1.1 400错误请求
<服务器:Apache-Coyote / 1.1
& Cache-Control:no-cache
<到期日:Thu,01 Jan 1970 00:00:00 GMT
< Pragma:no-cache
< Content-Type:application / json; charset = UTF-8
<传输编码:分块
<日期:星期四,2015年8月13日12:49:46 GMT
<连接:close
<
但这一个:
curl -HOrigin:http://www.microsoft.com--verbosehttp:// localhost:8080 / alfresco / service / api / whatever
* Trying :: 1 ...
*连接到localhost(:: 1)端口8080(#0)
> GET / alfresco / service / api / whatever HTTP / 1.1
>主机:localhost:8080
> User-Agent:curl / 7.43.0
>接受:* / *
>原产地:http://www.microsoft.com
>
< HTTP / 1.1 404未找到
<服务器:Apache-Coyote / 1.1
& Access-Control-Allow-Credentials:true
< Access-Control-Allow-Origin:http://www.microsoft.com
<变化:原因
< Cache-Control:no-cache
<到期日:Thu,01 Jan 1970 00:00:00 GMT
< Pragma:no-cache
< Content-Type:text / html; charset = UTF-8
<传输编码:分块
<日期:星期四,2015年8月13日12:52:15 GMT
<
我也尝试过Tomcat的CORS过滤器,结果相同。
< filter>
< filter-name> CorsFilter< / filter-name>
< filter-class> org.apache.catalina.filters.CorsFilter< / filter-class>
< / filter>
< filter-mapping>
< filter-name> CorsFilter< / filter-name>
< url-pattern> / *< / url-pattern>
< / filter-mapping>
问题:
(1)我缺少的东西在客户端/ AngularJS $ http一边?我应该使用一个angular-http-interceptor? (对不起,相当新的AngularJS)。我认为这很可能是这里的原因,但不知道缺少什么。
(2)我不明白为什么CORS过滤器不会添加'Access -Control-Allow-Origin'头部到这两个响应,但只对一个API调用,因为两个API urls开始于/ alfresco / service,这应该由CORS过滤器按
< url-模式> / service / *< / url-pattern>
(为什么它适用于一个API网址,只是区别我看到的是,在一种情况下,我已经验证和使用alf_ticket,在另一种情况下,我不是,但即使我添加一个(不必要的)alf_ticket登录调用,它不会任何差异。)
(3)为什么它在IE中工作呢? (顺便说一下:使用Chrome扩展程序 https:// chrome。 google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi 它也可以在Chrome中使用。)
相关问题:使用REST Alfresco 进行跨域调用
解决方案我有同样的问题,由于某种原因登录apiGET调用不返回访问控制允许原因的标题。解决方法:POST调用正常!
I have some problem with Alfresco (5.0.d), my AngularJS (1.4.3) client and the CORS settings (typical cross-domain / No'Access-Control-Allow-Origin' header is present on the requested resource problem).
I am calling the Alfresco REST API from an AngularJS application running on localhost:3000, to an Alfresco instance running on localhost:8080 (Tomcat, no reverse-proxy in front).
This XHR call works fine:
This one
http://localhost:8080/alfresco/service/api/login?u=admin&pw=admin
only works fine in Internet Explorer 11, but in Chrome and Firefox, I am getting status code 200 returned with 0 bytes and the error in the JS console:
XMLHttpRequest cannot load http://localhost:8080/alfresco/service/api/login?u=admin&pw=admin. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access.
In the Alfresco web.xml, I have enabled the CORS filter as follows:
<!-- CORS Filter Mappings Begin --> <filter-mapping> <filter-name>CORS</filter-name> <url-pattern>/api/*</url-pattern> <url-pattern>/service/*</url-pattern> <url-pattern>/s/*</url-pattern> <url-pattern>/cmisbrowser/*</url-pattern> </filter-mapping> <!-- CORS Filter Mappings End --> <!-- CORS Filter Begin --> <filter> <filter-name>CORS</filter-name> <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> <init-param> <param-name>cors.allowGenericHttpRequests</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>cors.allowOrigin</param-name> <!-- <param-value>http://localhost:3000 http://localhost:8081 http://localhost:8080 https://localhost</param-value> --> <param-value>*</param-value> </init-param> <init-param> <param-name>cors.allowSubdomains</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>cors.supportedMethods</param-name> <param-value>GET, HEAD, POST, PUT, DELETE, OPTIONS</param-value> </init-param> <init-param> <param-name>cors.supportedHeaders</param-name> <param-value>origin, authorization, x-file-size, x-file-name, content-type, accept, x-file-type</param-value> </init-param> <init-param> <param-name>cors.supportsCredentials</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>cors.maxAge</param-name> <param-value>3600</param-value> </init-param> </filter>--> <!-- CORS Filter End -->
The calls from within Angular:
The one that works fine:
$http.get('http://localhost:8080/alfresco/service/slingshot/live-search-docs?t=Project&alf_ticket=TICKET_9d9780c83b8b9525c7acb9d3d8da66c5c902fb76').then(function(response) { console.log('DATA LOADED: ' + response.items); $scope.contents = response.items; });
Response headers:
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Cache-Control: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Pragma: no-cache Content-Type: application/json;charset=UTF-8 Content-Length: 85 Date: Thu, 13 Aug 2015 06:37:24 GMT
The one that fails:
$http.get('http://localhost:8080/alfresco/service/api/login?u=' + $scope.user.email + '&pw=' + $scope.user.password). then(function(response) { console.log('ALF_TICKET: ' + response.data.ticket); $scope.alfTicket = response.data.ticket; $state.go('admin-panel.default.introduction'); }, function(response) { console.log('LOGIN FAILED'); });
Response headers:
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Access-Control-Allow-Credentials: true Access-Control-Allow-Origin: http://localhost:3000 Vary: Origin Cache-Control: no-cache Expires: Thu, 01 Jan 1970 00:00:00 GMT Pragma: no-cache Content-Type: application/json;charset=UTF-8 Transfer-Encoding: chunked Date: Thu, 13 Aug 2015 06:38:36 GMT
I have the $httpProvider configured in my AngularJS app, just to be sure:
.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.useXDomain = true; delete $httpProvider.defaults.headers.common['X-Requested-With']; }
A CURL request simulated from a different host works fine, interestingly though, I do not get a
Access-Control-Allow-Origin
header back in the response despite the CORS filter enabled in Alfresco:curl -H "Origin: http://www.microsoft.com" --verbose "http://alfresco.mycompany.ch:8080/alfresco/service/api/login?u=admin&pw=12@echo" * Hostname was NOT found in DNS cache * Trying 10.10.0.183... * Connected to alfresco.mycompany.ch (10.10.0.183) port 8080 (#0) > GET /alfresco/service/api/login?u=admin&pw=12@echo HTTP/1.1 > User-Agent: curl/7.37.1 > Host: alfresco.mycompany.ch:8080 > Accept: */* > Origin: http://www.microsoft.com > < HTTP/1.1 200 OK * Server Apache-Coyote/1.1 is not blacklisted < Server: Apache-Coyote/1.1 < Cache-Control: no-cache < Expires: Thu, 01 Jan 1970 00:00:00 GMT < Pragma: no-cache < Content-Type: application/json;charset=UTF-8 < Content-Length: 85 < Date: Thu, 13 Aug 2015 08:11:15 GMT < { "data": { "ticket":"TICKET_7d07634afbb25a7e823c0348d907e0790eeff97e" } } * Connection #0 to host alfresco.mycompany.ch left intact
therefore I think it's client/AngularJS related.
=== Update 1: ===
I tried to add an interceptor to the $httpProvider as below, but it doesn't help. I don't see the headers I am setting there in any of the responses, although the interceptor gets called.
$httpProvider.interceptors.push(function() { return { 'request': function(request) { return request; }, 'response': function(response) { console.log('Interceptor called.'); response.config.headers['MyTestHeader'] = '12345'; response.config.headers['Access-Control-Allow-Origin'] = '*'; return response; } }; });
=== Update 2: ===
Some more findings, but now a bit weird on the Alfresco side. I am doing two almost similar API calls, to the following two urls:
- http://localhost:8080/alfresco/service/api/login
- http://localhost:8080/alfresco/service/api/whatever
You can see, they only differ at the end. The one with
/whatever
returns aAccess-Control-Allow-Origin
response header, the one with/login
does not. It must be related to the Alfresco config / webscript, but I have not yet found the origin of it.curl -H "Origin: http://www.microsoft.com" --verbose "http://localhost:8080/alfresco/service/api/login" * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /alfresco/service/api/login HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.43.0 > Accept: */* > Origin: http://www.microsoft.com > < HTTP/1.1 400 Bad Request < Server: Apache-Coyote/1.1 < Cache-Control: no-cache < Expires: Thu, 01 Jan 1970 00:00:00 GMT < Pragma: no-cache < Content-Type: application/json;charset=UTF-8 < Transfer-Encoding: chunked < Date: Thu, 13 Aug 2015 12:49:46 GMT < Connection: close <
But this one:
curl -H "Origin: http://www.microsoft.com" --verbose "http://localhost:8080/alfresco/service/api/whatever" * Trying ::1... * Connected to localhost (::1) port 8080 (#0) > GET /alfresco/service/api/whatever HTTP/1.1 > Host: localhost:8080 > User-Agent: curl/7.43.0 > Accept: */* > Origin: http://www.microsoft.com > < HTTP/1.1 404 Not Found < Server: Apache-Coyote/1.1 < Access-Control-Allow-Credentials: true < Access-Control-Allow-Origin: http://www.microsoft.com < Vary: Origin < Cache-Control: no-cache < Expires: Thu, 01 Jan 1970 00:00:00 GMT < Pragma: no-cache < Content-Type: text/html;charset=UTF-8 < Transfer-Encoding: chunked < Date: Thu, 13 Aug 2015 12:52:15 GMT <
I also tried the CORS filter of Tomcat instead, same result.
<filter> <filter-name>CorsFilter</filter-name> <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> </filter> <filter-mapping> <filter-name>CorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
Questions:
(1) Am I missing something on the client/AngularJS $http side? Should I use a angular-http-interceptor? (Sorry, pretty new to AngularJS). I think that this is most probably the reason here, but not sure what's missing.
(2) I don't see why the CORS filter would not add the 'Access-Control-Allow-Origin' header to both responses but only to the one API call, since both API urls start with /alfresco/service, which should be handled by the CORS filter as per
<url-pattern>/service/*</url-pattern>
(And why does it work for one API url, but for the other it does not? Only difference I see is that in one case, I am already authenticated and use an alf_ticket, in the other case I am not. But even if I add an (unnecessary) alf_ticket to the login call, it does not make any difference.)
(3) Why does it work in IE then at all? (by the way: with the Chrome extension https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi it also works in Chrome.)
Related SO question: cross domain call using REST Alfresco
解决方案I have the same issue, for some reason the login api "GET" call does not return "Access-Control-Allow-Origin" in the headers. WORKAROUND: The "POST" call works fine!
这篇关于AngularJS / Alfresco / CORS过滤器问题:没有“Access-Control-Allow-Origin”头的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!