【问题标题】:Spring CORS No 'Access-Control-Allow-Origin' header is presentSpring CORS 不存在“Access-Control-Allow-Origin”标头
【发布时间】:2016-05-07 14:26:20
【问题描述】:

将 web.xml 移植到 java config 后出现以下问题

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

基于一些Spring引用,尝试了以下尝试:

@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
        @Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
                .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
                        "Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
                .allowCredentials(true).maxAge(3600);
    }

}

选择的值取自一个有效的 web.xml 过滤器:

<filter>    
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
</init-param> </filter> <filter-mapping>

<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

任何想法为什么 Spring java config 方法不像 web.xml 文件那样工作?

【问题讨论】:

    标签: spring spring-mvc cors


    【解决方案1】:

    如果您想允许所有来源(*),请使用 setAllowedOriginPatterns 而不是 setAllowedOrigins

    您可以点击以下链接

    https://github.com/spring-projects/spring-framework/issues/26111

    【讨论】:

      【解决方案2】:

      我通过使用 @CrossOrigin 注释在 Spring Boot 中找到了解决方案。

      @Configuration
      @CrossOrigin
      public class WebConfig extends WebMvcConfigurerAdapter {
      
          @Override
          public void addCorsMappings(CorsRegistry registry) {
              registry.addMapping("/**");
          }
      }
      

      【讨论】:

        【解决方案3】:

        我以这种方式解决了同样的问题。基本上添加这个@EnableWebSecurity注解并添加protected void configure(HttpSecurity http) throws Exception {}

        从此改变:

        @Configuration
        public class WebConfig {
        
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**").allowedMethods("*");
                }
            };
        }
        

        }

        到这里

        @Configuration
        @EnableWebSecurity
        public class WebConfig extends WebSecurityConfigurerAdapter {
        
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.antMatcher("/**").authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated();
            http.cors().and().csrf().disable();
        }
        
        @Bean
        public WebMvcConfigurer corsConfigurer() {
            return new WebMvcConfigurer() {
                @Override
                public void addCorsMappings(CorsRegistry registry) {
                    registry.addMapping("/**").allowedMethods("*");
                }
            }; 
          }
        }
        

        【讨论】:

          【解决方案4】:

          经过大量的尝试和研究,这就是我解决 Access-Control-Allow-Origin 存在”问题的方法。

          添加Spring security后,很多开发者面临cross origin问题,这就是解决这个问题的方法。

          1. 添加自定义过滤器类的定义

            public class CsrfTokenLogger implements Filter {
            
             private Logger logger =
                  Logger.getLogger(CsrfTokenLogger.class.getName());
            
            @Override
            public void doFilter(
            ServletRequest request, 
            ServletResponse response, 
            FilterChain filterChain) 
              throws IOException, ServletException {
            
              Object o = request.getAttribute("_csrf");
              CsrfToken token = (CsrfToken) o;
            
             filterChain.doFilter(request, response);
              }
             }
            
          2. 在配置类中添加自定义过滤器

            @Configuration
            public class ProjectConfig extends WebSecurityConfigurerAdapter {
            
            @Override
            protected void configure(HttpSecurity http) 
            throws Exception {
            
            http.addFilterAfter(
                    new CsrfTokenLogger(), CsrfFilter.class)
                .authorizeRequests()
                    .antMatchers("/login*").permitAll()
                    .anyRequest().authenticated();
             }
            }
            

          【讨论】:

            【解决方案5】:

            公共类 TrackingSystemApplication {

                public static void main(String[] args) {
                    SpringApplication.run(TrackingSystemApplication.class, args);
                }
            
                @Bean
                public WebMvcConfigurer corsConfigurer() {
                    return new WebMvcConfigurerAdapter() {
                        @Override
                        public void addCorsMappings(CorsRegistry registry) {
                            registry.addMapping("/**").allowedOrigins("http://localhost:4200").allowedMethods("PUT", "DELETE",
                                    "GET", "POST");
                        }
                    };
                }
            
            }
            

            【讨论】:

              【解决方案6】:

              由于某种原因,如果仍然有人无法绕过 CORS,请写下哪个浏览器想要访问您的请求的标头。

              在你的配置文件中添加这个 bean。

              @Bean
              public WebSecurityConfigurerAdapter webSecurity() {
                  return new WebSecurityConfigurerAdapter() {
              
                      @Override
                      protected void configure(HttpSecurity http) throws Exception {
                          http.headers().addHeaderWriter(
                                  new StaticHeadersWriter("Access-Control-Allow-Origin", "*"));
              
              
                      }
                  };
              }
              

              通过这种方式,我们可以告诉浏览器我们允许来自所有来源的跨域。如果您想限制特定路径,请将“*”更改为 {'http://localhost:3000',""}。

              了解此行为的帮助参考https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example

              【讨论】:

                【解决方案7】:

                正如@Geoffrey 指出的那样,使用弹簧安全性,您需要一种不同的方法,如下所述: Spring Boot Security CORS

                【讨论】:

                  【解决方案8】:

                  我也收到了类似No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.的消息

                  我已经正确配置了 cors,但是 RouterFuncion 中的 webflux 中缺少的是接受和内容类型标头 APPLICATION_JSON,就像这段代码中一样:

                  @Bean
                  RouterFunction<ServerResponse> routes() {
                      return route(POST("/create")
                                                .and(accept(APPLICATION_JSON))
                                                .and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
                  }
                  

                  【讨论】:

                    【解决方案9】:

                    Omkar 的回答相当全面。

                    但全局配置部分的某些部分已更改。

                    根据spring boot 2.0.2.RELEASE reference

                    从 4.2 版开始,Spring MVC 支持 CORS。使用控制器方法 在 Spring Boot 中使用 @CrossOrigin 注释的 CORS 配置 应用程序不需要任何特定配置。全球 CORS 可以通过注册 WebMvcConfigurer bean 来定义配置 使用自定义的 addCorsMappings(CorsRegistry) 方法,如 下面的例子:

                    @Configuration
                    public class MyConfiguration {
                    
                        @Bean
                        public WebMvcConfigurer corsConfigurer() {
                            return new WebMvcConfigurer() {
                                @Override
                                public void addCorsMappings(CorsRegistry registry) {
                                    registry.addMapping("/api/**");
                                }
                            };
                        }
                    }
                    

                    不过,这篇文章中的大多数答案都使用WebMvcConfigurerAdapter

                    The type WebMvcConfigurerAdapter is deprecated

                    从 Spring 5 开始你只需要实现接口 WebMvcConfigurer:

                    public class MvcConfig implements WebMvcConfigurer {
                    

                    这是因为 Java 8 在接口上引入了默认方法 涵盖 WebMvcConfigurerAdapter 类的功能

                    【讨论】:

                      【解决方案10】:

                      根据 Omar 的回答,我在我的 REST API 项目中创建了一个名为 WebConfig.java 的新类文件,配置如下:

                      @Configuration
                      @EnableWebMvc
                      public class WebConfig extends WebMvcConfigurerAdapter {
                      
                        @Override
                        public void addCorsMappings(CorsRegistry registry) {
                          registry.addMapping("/**").allowedOrigins("*");
                        }
                      } 
                      

                      这允许任何源访问 API 并将其应用于 Spring 项目中的所有控制器。

                      【讨论】:

                        【解决方案11】:

                        有用的提示 - 如果您使用 Spring 数据休息,您需要一种不同的方法。

                        @Component
                        public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {
                        
                         @Override
                         public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
                            config.getCorsRegistry().addMapping("/**")
                                    .allowedOrigins("http://localhost:9000");
                          }
                        }
                        

                        【讨论】:

                        • 感谢这篇文章。当我注意到你的帖子说 Spring Data REST 使用不同的方法时,我有点失去希望了。现在完全适合我!
                        • RepositoryRestConfigurerAdapter 已弃用。直接实现RepositoryRestConfigurer即可。
                        【解决方案12】:

                        我们遇到了同样的问题,我们使用 Spring 的 XML 配置解决了它,如下所示:

                        将此添加到您的上下文 xml 文件中

                        <mvc:cors>
                            <mvc:mapping path="/**"
                                allowed-origins="*"
                                allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
                                allowed-methods="GET, PUT, POST, DELETE"/>
                        </mvc:cors>
                        

                        【讨论】:

                          【解决方案13】:

                          addCorsMappings 方法中将 CorsMapping 从 registry.addMapping("/*") 更改为 registry.addMapping("/**")

                          查看这个春季 CORS Documentation

                          来自documentation -

                          为整个应用启用 CORS 非常简单:

                          @Configuration
                          @EnableWebMvc
                          public class WebConfig extends WebMvcConfigurerAdapter {
                          
                              @Override
                              public void addCorsMappings(CorsRegistry registry) {
                                  registry.addMapping("/**");
                              }
                          }
                          

                          您可以轻松更改任何属性,以及仅将此 CORS 配置应用于特定路径模式:

                          @Configuration
                          @EnableWebMvc
                          public class WebConfig extends WebMvcConfigurerAdapter {
                              @Override
                              public void addCorsMappings(CorsRegistry registry) {
                                  registry.addMapping("/api/**")
                                      .allowedOrigins("http://domain2.com")
                                      .allowedMethods("PUT", "DELETE")
                                      .allowedHeaders("header1", "header2", "header3")
                                      .exposedHeaders("header1", "header2")
                                      .allowCredentials(false).maxAge(3600);
                              }
                          }
                          

                          Controller method CORS configuration

                          @RestController
                          @RequestMapping("/account")
                          public class AccountController {
                            @CrossOrigin
                            @RequestMapping("/{id}")
                            public Account retrieve(@PathVariable Long id) {
                              // ...
                            }
                          }
                          

                          为整个控制器启用 CORS -

                          @CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
                          @RestController
                          @RequestMapping("/account")
                          public class AccountController {
                          
                              @RequestMapping("/{id}")
                              public Account retrieve(@PathVariable Long id) {
                                  // ...
                              }
                          
                              @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
                              public void remove(@PathVariable Long id) {
                                  // ...
                              }
                          }
                          

                          您甚至可以同时使用控制器级别和方法级别的 CORS 配置;然后 Spring 将结合两个注解的属性来创建合并的 CORS 配置。

                          @CrossOrigin(maxAge = 3600)
                          @RestController
                          @RequestMapping("/account")
                          public class AccountController {
                          
                              @CrossOrigin("http://domain2.com")
                              @RequestMapping("/{id}")
                              public Account retrieve(@PathVariable Long id) {
                                  // ...
                              }
                          
                              @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
                              public void remove(@PathVariable Long id) {
                                  // ...
                              }
                          }
                          

                          【讨论】:

                          • 为整个应用程序启用 CORS 对我不起作用。
                          • 使用addCorsMapping 对我不起作用,我想说这是因为弹簧安全性...,但是按照here 的建议添加corsConfigurationSource bean 解决了我的问题。
                          • 也不要忘记允许所有客户端 registry.addMapping("/**").allowedOrigins("*"); spring.io/guides/gs/rest-service-cors
                          • 你是真正的救星。我正在使用 Spring 4.2 并尝试了无数其他替代方案,但在我尝试 addCorsMappings 覆盖方式之前,它们都无法正常工作。添加标准 CORS 标头以及 Access-Control-Allow-Headers 可能有帮助,也可能没有帮助
                          • 2020年了,spring boot注解还是不行。
                          【解决方案14】:

                          如果您使用 Spring Security 版本 >= 4.2,则可以使用 Spring Security 的原生支持而不是包括 Apache:

                          @Configuration
                          @EnableWebMvc
                          public class WebConfig extends WebMvcConfigurerAdapter {
                          
                              @Override
                              public void addCorsMappings(CorsRegistry registry) {
                                  registry.addMapping("/**");
                              }
                          }
                          

                          上面的示例是从 Spring blog post 复制的,您还可以在其中找到有关如何在控制器上配置 CORS、特定控制器方法等的信息。此外,还有 XML 配置示例以及 Spring Boot 集成.

                          【讨论】:

                            猜你喜欢
                            • 2016-10-30
                            • 1970-01-01
                            • 2016-10-30
                            • 2019-06-19
                            • 2021-05-23
                            • 2016-11-06
                            • 2017-12-11
                            • 2014-08-20
                            相关资源
                            最近更新 更多