很抱歉发布这个相当大的帖子。但我看不出有办法让它变得更小。责备CORS :)
版本:
- Angularjs 版本:1.1.3
- 码头版本:8.1.9
- Jetty Servlets 版本:8.1.9.v20130131(用于 Jettys CrossOriginFilter)
我想要达到的目标
使用基本授权标头的跨域请求:
- 来自 Angularjs 的 $http 方法来自 localhost:8000
- 到 localhost:8080/api/user(Spring MVC REST 接口)。
问题:
- HTTPFox 显示对 /api/user 的 OPTIONS 请求被拒绝,响应为 302 (NS_ERROR_DOM_BAD_URI)
- 如果发送 Authorization Basic 标头,服务器将响应 302 而不是 200。
- 所谓的简单 CORS 标头工作(没有 Angularjs 授权基本标头集)。
- Angularjs 返回 0 作为状态(而不是 302 或 200)。
- 在 HTTPFox Location 的响应标头中,标头重定向好像授权失败
- 使用 Curl 进行测试(带有授权标头集)可以正常工作
- 提供的 Base64 编码的授权字符串是正确的。
问题:
- OPTIONS 302 (NS_ERROR_DOM_BAD_URI) 的原因是什么?我该如何解决?
- 为什么 Angularjs 返回 0 而不是 302 或 200(似乎是 x-requested-with 的问题)?
- 在浏览器中使用 Cross Origin 真的是生产的好主意吗(似乎有很多问题)?
Spring配置的web.xml中的CORS设置:
allowedOrigins: *
allowedMethods: GET,POST,DELETE,PUT,HEAD,OPTIONS
allowedHeaders: origin,content-type,accept,authorization,x-requested-with
supportsCredentials: true
Angularjs http 请求(来源:localhost:8000):
$http.get('localhost:8080/api/user', {headers: {'Authorization':'Basic am9obkBqb2huLmNvbTpibGE='}})
.success(function(data, status, head, config) {
console.log("success");
console.log(status);
})
.error(function(data, status, head, config) {
console.log("error");
console.log(status);
});
HTTPFox 请求标头(来自失败的 OPTIONS 请求):
(Request-Line) OPTIONS /api/user HTTP/1.1
Host localhost:8080
User-Agent Mozilla/5.0 (X11; Linux x86_64; rv:19.0) Gecko/20100101 Firefox/19.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-US,en;q=0.5
Accept-Encoding gzip, deflate DNT 1
Origin localhost:8000
Access-Control-Request-Method GET
Access-Control-Request-Headers authorization
Connection keep-alive
HTTPFox 响应标头(来自失败的 OPTIONS 请求):
(Status-Line) HTTP/1.1 302 Found
Access-Control-Allow-Origin localhost:8000
Access-Control-Allow-Credentials true
Access-Control-Max-Age 1800
Access-Control-Allow-Methods GET,POST,DELETE,PUT,HEAD,OPTIONS
Access-Control-Allow-Headers origin, content-type, accept, authorization, x-requested-with
Location localhost:8080/login.jsp
Content-Length 0
Server Jetty(8.1.9.v20130131)
春季调试日志:
[qtp1172726060-24 - /api/user] DEBUG org.eclipse.jetty.server.Server - REQUEST /api/user on AsyncHttpConnection@c114739,g=HttpGenerator{s=0,h=-1,b=-1,c=-1},p=HttpParser{s=-5,l=10,c=0},r=1
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlet.ServletHandler - chain=CORS->springSecurityFilterChain->spring
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlet.ServletHandler - call filter CORS
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Cross-origin request to /api/user is a preflight cross-origin request
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Access-Control-Request-Method is GET
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Method GET is among allowed methods [GET, POST, DELETE, PUT, HEAD, OPTIONS]
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Access-Control-Request-Headers is authorization
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Headers [authorization] are among allowed headers [origin, content-type, accept, authorization, x-requested-with]
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlets.CrossOriginFilter - Preflight cross-origin request to /api/user forwarded to application
[qtp1172726060-24 - /api/user] DEBUG o.e.jetty.servlet.ServletHandler - call filter springSecurityFilterChain
[qtp1172726060-24 - /api/user] DEBUG org.eclipse.jetty.server.Server - RESPONSE /api/user 302 handled=true
[qtp1172726060-24] DEBUG o.e.jetty.server.AsyncHttpConnection - Enabled read interest SCEP@5deb702b{l(/127.0.0.1:41667)<->r(/127.0.0.1:8080),d=true,open=true,ishut=false,oshut=false,rb=false,wb=false,w=true,i=0r}-{AsyncHttpConnection@c114739,g=HttpGenerator{s=4,h=0,b=-1,c=-1},p=HttpParser{s=0,l=10,c=0},r=1}
Web.xml:
<!-- CORS related filter (this comes before the security filter -->
<filter>
<filter-name>CORS</filter-name>
<filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
<init-param>
<param-name>allowedOrigins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>allowedMethods</param-name>
<param-value>GET,POST,DELETE,PUT,HEAD,OPTIONS</param-value>
</init-param>
<init-param>
<param-name>allowedHeaders</param-name>
<param-value>origin, content-type, accept, authorization, x-requested-with</param-value>
</init-param>
<init-param>
<param-name>supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Security related filter -->
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>