Spring 云 - Zuul 代理正在生成否 'Access-Control-Allow-Origin' ajax 响应
Spring Cloud - Zuul Proxy is producing a No 'Access-Control-Allow-Origin' ajax response
启动应用程序:
@SpringBootApplication
@EnableZuulProxy
public class ZuulServer {
public static void main(String[] args) {
new SpringApplicationBuilder(ZuulServer.class).web(true).run(args);
}
}
我的 YAML 文件是这样的:
server:
port:8080
spring:
application:
name: zuul
eureka:
client:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
zuul:
proxy:
route:
springapp: /springapp
我有一个名为 springapp 的微服务应用程序(在端口 8081 上),并且有一些休息服务。下面是我的客户 UI app:
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="js/libs/jquery/jquery.min.js" ></script>
</head>
<body>
<script type="text/javascript">
$.ajax({
url: 'http://localhost:8080/zuul/springapp/departments',
type: 'GET'
}).done(function (data) {
consoe.log(data);
document.write(data);
});
</script>
</body>
</html>
但是我得到了
XMLHttpRequest cannot load http://localhost:8080/zuul/springapp/departments. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8383' is therefore not allowed access.
这个 UI HTML5 应用程序在 http://localhost:8383/SimpleAPp/index.html. CORS, CORS, CORS... Please help. BTW the http://localhost:8080/zuul/springapp/departments returns a json list as supposed to when on the browser address bar. The spring.io blog here 上说不需要过滤器,因为 zuulproxy 会处理它,但我不知道为什么不需要为我工作。
那只是浏览器告诉你你违反了它的共同来源政策(参见 Wikipedia entry 和互联网上的大量 material,其中 none 确实与您添加的标签)。您可以通过服务 CORS 飞行前检查(例如在 Filter
中)告诉浏览器可以从不同的地址加载资源,或者通过代理加载 HTML(提示:后者更容易,更不容易出错)。
当您的应用程序在 http://localhost:8383
上运行时,您只能对 http://localhost:8383
进行 AJAX 调用。 Zuul 不会也不能改变它。
Zuul 可以做的是映射请求,例如http://localhost:8383/zuul/
到 http://localhost:8080/zuul/
。但是您的浏览器必须调用 http://localhost:8383/zuul/springapp/departments
并且您必须配置该映射。
将这段代码添加到带有 @EnableZuulProxy 注释的 class 中应该可以解决问题。
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
我有一个类似的问题,Angular Web 应用程序使用 RESTful 由 Spring Boot with Zuul 和 Spring Security 实现的服务。
None 以上解决方案有效。我意识到问题不在 Zuul 中,而是在 Spring 安全性中。
正如官方文档 (CORS with Spring Security) 所述,当使用 Spring 安全性时,必须在 Spring 安全性之前配置 CORS。
最后,我能够将 Grinish Nepal 的(参见之前的答案)解决方案集成到一个有效的解决方案中。
事不宜迟,下面是使用 Spring Security 和 Zuul 启用 CORS 的代码:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//irrelevant for this problem
@Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//configure CORS -- uses a Bean by the name of corsConfigurationSource (see method below)
//CORS must be configured prior to Spring Security
.cors().and()
//configuring security - irrelevant for this problem
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
//irrelevant for this problem
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
//The CORS filter bean - Configures allowed CORS any (source) to any
//(api route and method) endpoint
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin(CorsConfiguration.ALL);
config.addAllowedHeaders(Collections.singletonList(CorsConfiguration.ALL));
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return source;
}
//configuring BA usernames and passwords - irrelevant for this problem
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
...
}
}
我有同样的问题,我已经通过添加 CorsFilter bean 解决了
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
并在这段代码中添加 zuul 的属性
zuul:
sensitiveHeaders:
ignored-headers: Access-Control-Allow-Credentials, Access-Control-Allow-Origin
您可以找到有关该问题的更多详细信息here
只需将以下内容添加到对我有用的配置中
zuul:
ignoredHeaders: Access-Control-Allow-Credentials, Access-Control-Allow-Origin
对于那些即使添加 @Bean CorsFilter
仍然有问题的人,请检查控制器是否也用 @CrossOrigin
注释,这种 CORS 重复,在控制器级别和 Zuul 代理可能导致问题。
启动应用程序:
@SpringBootApplication
@EnableZuulProxy
public class ZuulServer {
public static void main(String[] args) {
new SpringApplicationBuilder(ZuulServer.class).web(true).run(args);
}
}
我的 YAML 文件是这样的:
server:
port:8080
spring:
application:
name: zuul
eureka:
client:
enabled: true
serviceUrl:
defaultZone: http://localhost:8761/eureka/
zuul:
proxy:
route:
springapp: /springapp
我有一个名为 springapp 的微服务应用程序(在端口 8081 上),并且有一些休息服务。下面是我的客户 UI app:
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript" src="js/libs/jquery/jquery.min.js" ></script>
</head>
<body>
<script type="text/javascript">
$.ajax({
url: 'http://localhost:8080/zuul/springapp/departments',
type: 'GET'
}).done(function (data) {
consoe.log(data);
document.write(data);
});
</script>
</body>
</html>
但是我得到了
XMLHttpRequest cannot load http://localhost:8080/zuul/springapp/departments. No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:8383' is therefore not allowed access.
这个 UI HTML5 应用程序在 http://localhost:8383/SimpleAPp/index.html. CORS, CORS, CORS... Please help. BTW the http://localhost:8080/zuul/springapp/departments returns a json list as supposed to when on the browser address bar. The spring.io blog here 上说不需要过滤器,因为 zuulproxy 会处理它,但我不知道为什么不需要为我工作。
那只是浏览器告诉你你违反了它的共同来源政策(参见 Wikipedia entry 和互联网上的大量 material,其中 none 确实与您添加的标签)。您可以通过服务 CORS 飞行前检查(例如在 Filter
中)告诉浏览器可以从不同的地址加载资源,或者通过代理加载 HTML(提示:后者更容易,更不容易出错)。
当您的应用程序在 http://localhost:8383
上运行时,您只能对 http://localhost:8383
进行 AJAX 调用。 Zuul 不会也不能改变它。
Zuul 可以做的是映射请求,例如http://localhost:8383/zuul/
到 http://localhost:8080/zuul/
。但是您的浏览器必须调用 http://localhost:8383/zuul/springapp/departments
并且您必须配置该映射。
将这段代码添加到带有 @EnableZuulProxy 注释的 class 中应该可以解决问题。
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
我有一个类似的问题,Angular Web 应用程序使用 RESTful 由 Spring Boot with Zuul 和 Spring Security 实现的服务。
None 以上解决方案有效。我意识到问题不在 Zuul 中,而是在 Spring 安全性中。
正如官方文档 (CORS with Spring Security) 所述,当使用 Spring 安全性时,必须在 Spring 安全性之前配置 CORS。
最后,我能够将 Grinish Nepal 的(参见之前的答案)解决方案集成到一个有效的解决方案中。
事不宜迟,下面是使用 Spring Security 和 Zuul 启用 CORS 的代码:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
//irrelevant for this problem
@Autowired
private MyBasicAuthenticationEntryPoint authenticationEntryPoint;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//configure CORS -- uses a Bean by the name of corsConfigurationSource (see method below)
//CORS must be configured prior to Spring Security
.cors().and()
//configuring security - irrelevant for this problem
.authorizeRequests()
.anyRequest().authenticated()
.and()
.httpBasic()
.authenticationEntryPoint(authenticationEntryPoint);
//irrelevant for this problem
http.addFilterAfter(new CustomFilter(),
BasicAuthenticationFilter.class);
}
//The CORS filter bean - Configures allowed CORS any (source) to any
//(api route and method) endpoint
@Bean
CorsConfigurationSource corsConfigurationSource() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin(CorsConfiguration.ALL);
config.addAllowedHeaders(Collections.singletonList(CorsConfiguration.ALL));
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return source;
}
//configuring BA usernames and passwords - irrelevant for this problem
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
...
}
}
我有同样的问题,我已经通过添加 CorsFilter bean 解决了
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
并在这段代码中添加 zuul 的属性
zuul:
sensitiveHeaders:
ignored-headers: Access-Control-Allow-Credentials, Access-Control-Allow-Origin
您可以找到有关该问题的更多详细信息here
只需将以下内容添加到对我有用的配置中
zuul:
ignoredHeaders: Access-Control-Allow-Credentials, Access-Control-Allow-Origin
对于那些即使添加 @Bean CorsFilter
仍然有问题的人,请检查控制器是否也用 @CrossOrigin
注释,这种 CORS 重复,在控制器级别和 Zuul 代理可能导致问题。