【问题标题】:Spring Cloud - Zuul Proxy is producing a No 'Access-Control-Allow-Origin' ajax responseSpring Cloud - Zuul 代理正在生成 No 'Access-Control-Allow-Origin' ajax 响应
【发布时间】:2015-04-24 14:11:12
【问题描述】:

启动应用程序:

@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 应用:

    <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 ...请帮助。顺便说一句,http://localhost:8080/zuul/springapp/departments 在浏览器地址栏上返回一个 json 列表。 spring.io 博客here 说不需要过滤器,因为 zuulproxy 负责处理,但我不知道为什么它不适合我。

【问题讨论】:

    标签: java spring spring-boot spring-cloud netflix-zuul


    【解决方案1】:

    将这段代码添加到使用@EnableZuulProxy 注释的类中应该可以解决问题。

    @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);
    }
    

    【讨论】:

    • 这行得通,谢谢!!但是,这不应该是默认行为吗?
    • 你能提供完整的代码吗.. 我卡在这些问题上很久了
    • @Pallavi 你有什么问题这是设置 CORS 过滤器的完整代码。
    • @GrinishNepal 我只是想知道放置这些代码的正确位置,我尝试了多种组合。我的项目结构就像 Angular6 -> ApiGateway -> 微服务
    【解决方案2】:

    我遇到了类似的问题,Angular Web 应用程序使用由 Spring Boot 和 Zuul 和 Spring Security 实现的 RESTful 服务。

    上述解决方案均无效。我意识到问题不在于 Zuul,而在于 Spring Security。

    正如官方文档 (CORS with Spring Security) 所述,使用 Spring Security 时,必须在 Spring Security 之前配置 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 {
               ...
            }
        }
    

    【讨论】:

    • 这个类是加在zuul的应用还是有微服务的应用中?
    • @Mate 使用这些解决方案我收到弹出窗口,要求我输入用户名、密码。请帮我完成这些设置
    • @Pallavi 我上面的解决方案适用于在使用 Zuul 和 Spring Security 时尝试启用 CORS 的人,并使用某种身份验证方法。我的示例使用 .httpBasic() 身份验证,这就是为什么您的浏览器会在弹出窗口中询问用户名和密码的原因。如果您不需要 Spring Security,请使用接受的答案或尝试我的解决方案,删除 cmets 下的所有代码://配置安全性 - 与此问题无关,//与此问题无关,//配置 BA 用户名和密码 -与这个问题无关。希望这会有所帮助,如果可行,请告诉我。
    【解决方案3】:

    当您的应用程序在http://localhost:8383 上运行时,您只能对http://localhost:8383 进行AJAX 调用。 Zuul 没有也无法改变这一点。

    Zuul 可以做的是映射请求,例如http://localhost:8383/zuul/http://localhost:8080/zuul/。但是您的浏览器必须调用 http://localhost:8383/zuul/springapp/departments 并且您必须配置该映射。

    【讨论】:

    • 非常感谢。这对我有用 :) 我现在的另一个问题是:如果你有一个用 Cordova/Phonegap 包装的 Angular js 应用程序并在应用程序中使用静态文件而不是从代理服务器提供文件,你会怎么做?我问是因为我的解决方案目前只能工作,因为带有 ajax 请求的静态文件驻留在 ZuulProxy 服务器上。
    • 我有一个针对上述 angular.js 场景的解决方案。我向 ZuulProxy 添加了一个 CORS 过滤器,如图所示 here。因此,任何来自与代理相同域或来自其他来源的 ZuulProxy 请求都将被允许:)
    • 如果我假设正确,CORS Filter 仅在应用程序托管在根 (/) 上下文中时才有效。如果应用程序托管在任何其他上下文中,您需要回退为该 servlet 容器启用 CORS。
    【解决方案4】:

    我有同样的问题,我已经通过添加 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找到有关该问题的更多详细信息

    【讨论】:

      【解决方案5】:

      只需将以下内容添加到对我有用的配置中

      zuul:
          ignoredHeaders: Access-Control-Allow-Credentials, Access-Control-Allow-Origin
      

      【讨论】:

        【解决方案6】:

        这只是浏览器告诉你你违反了它的共同来源政策(见Wikipedia entry和互联网上的大量资料,这些资料都与你添加的标签无关)。您可以通过服务 CORS 飞行前检查(例如在 Filter 中)来教导浏览器可以从不同地址加载资源,或者通过代理加载 HTML(提示:后者更容易且更少容易出错)。

        【讨论】:

        • 感谢您尝试回答,但我添加标签的原因是因为来自 Spring Cloud 的 @EnableZuulProxy。在 spring.io blog 上的这篇文章中,他们说不需要您提到的那个过滤器,因为 ZuulProxy 为消费客户端做了一个反向代理。希望这是有道理的。
        • 是的,但正如@zeroflagL 下面所说,这意味着您必须通过代理发送所有请求。
        【解决方案7】:

        对于即使添加了@Bean CorsFilter 仍然存在问题的用户,请检查控制器是否也使用@CrossOrigin 进行注释,这种 CORS 在控制器级别和 Zuul 代理上的重复可能会导致问题。

        【讨论】:

          猜你喜欢
          • 2017-12-29
          • 2019-03-18
          • 2013-09-14
          • 1970-01-01
          • 2020-09-21
          • 2021-08-12
          • 2018-02-04
          • 2019-12-14
          • 1970-01-01
          相关资源
          最近更新 更多