【问题标题】:Spring Global CORS configuration not working but Controller level config doesSpring Global CORS 配置不起作用,但控制器级别配置起作用
【发布时间】:2016-10-25 03:44:29
【问题描述】:

我正在尝试通过WebMvcConfigurerAdapter 全局配置 CORS,如下所示。为了测试,我通过我创建的用于模拟外部服务的小型节点应用程序访问我的 API 端点。当我尝试这种方法时,响应不包含正确的标头并且失败并显示

XMLHttpRequest cannot load http://localhost:8080/api/query/1121. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:333' is therefore not allowed access.

全局配置

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

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

但是,当我像这样使用 @CrossOrigin 注释时,它可以很好地响应正确的标题。

@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*")
@RestController
@RequestMapping(value = "/api/query", produces = MediaType.APPLICATION_JSON_VALUE)
public class QueryController {
   ......
}

生产

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:333

使全局配置工作我缺少什么(按照此处的说明进行操作 https://spring.io/blog/2015/06/08/cors-support-in-spring-framework)。我觉得我错过了一些简单的东西,因为注释控制器工作得很好。

【问题讨论】:

  • 可能.allowedOrigins("*").allowedHeaders("*") 在全局配置中是多余的
  • 你弄明白了吗?我也有这个问题。尝试了下面的答案,但对我没有用...
  • @Will 我和你在同一条船上,但设法让某些东西发挥作用。看看我在这里的回答:stackoverflow.com/a/55629589/5877810

标签: java spring-mvc http-headers cors cross-domain


【解决方案1】:

我认为您的映射定义缺少*

registry.addMapping("/api/query/**")

没有额外的*,此配置不会映射到/api/query/1121 请求路径(但它可以在/api/query/5 上工作)。

【讨论】:

  • 感谢您的回复,我也尝试了"/api/query/**",但没有成功。最初我什至用registry.addMapping("/**") 实现了一个“hello world”类型的实现,但这并没有什么不同。我是否必须以某种方式指定它在端口8080 上?我什至不知道......它看起来应该可以正常工作
【解决方案2】:

您没有在其中声明方法,默认情况下只接受 get 方法。 试试registry.allowedMethods("*");

【讨论】:

  • 我在使用 POST 方法时遇到了同样的问题。它通过添加 allowedmethods 解决。
【解决方案3】:

为了使全局 CORS 配置起作用,客户端必须在 OPTIONS 请求中添加这两个标头。

Origin: http://host.com
Access-Control-Request-Method: POST

不过,@CrossOrigin 注释只需要“Origin”标头。
您的客户端可能添加了“Origin”标头,但缺少“Access-Control-Request-Method”......这就是为什么它适用于@CrossOrigin,但不适用于全局配置。

【讨论】:

  • 我收到 Refused to set unsafe header "Access-Control-Request-Method", chrome `83.0.4103.61 (Official Build) (64-bit)`
  • 如果代码在网络浏览器中运行,客户端不能这样做。
【解决方案4】:

我遇到了类似的问题。我将 WebMvcConfigurerAdapter 更改为 WebMvcConfigurationSupport 并开始工作。

除此之外,我还将xml配置文件中定义的RequestMappingHandlerMapping移动到java配置中。

【讨论】:

    【解决方案5】:

    在遇到此问题中记录的确切问题后,我能够使 Spring Global CORS 配置正常工作。我必须做两件事:

    1. 如果 allowCredentials 为真,allowedOrigins 不能为 *。这记录在 Mozilla.org

    2. 从 spring XML 中删除 mvc:annotation-driven。不能同时拥有 XML 配置和 @EnableWebMvc。如果没有@EnableWebMvc,全局类将无法工作,因此必须删除 mvc:annotation-driven。

    【讨论】:

      【解决方案6】:

      我遇到了类似的问题,但似乎没有任何方法有效(除了为每个控制器使用 @CrossOrigin 注释)。我遵循上面的Bharat Singh's 解决方案,并在对 Spring Framework 内部进行了一些调试之后 - 这对我有用(Spring Boot 2.0.6 + Spring Framework 5.0.10):

      @Configuration
      public class WebMvcConfiguration extends WebMvcConfigurationSupport {
      
      /* (non-Javadoc)
       * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
       */
      @Override
      protected void addCorsMappings(CorsRegistry registry) {
          //NOTE: servlet context set in "application.properties" is "/api" and request like "/api/session/login" resolves here to "/session/login"!
          registry.addMapping("/**")
              .allowedMethods("GET", "POST", "PUT", "DELETE")
              .allowedOrigins("*")
              .allowedHeaders("*")
              .allowCredentials(false);
          }
      }
      

      最初,当我使用 "/api/**" 映射时,它是在 Spring 中配置的,但是由于应用程序是使用 "/api" 上下文部署的 - 像 "/api/session/login" 这样的请求在内部映射到 "/session/login" 并且在 CORS 配置中找不到这样的映射- 请注意!

      【讨论】:

        【解决方案7】:

        我刚刚遇到了完全相同的问题,这个线程中的解决方案都没有工作。我设法用以下方法解决了它:

        一个新的配置bean:

        @Component
        @Order(Ordered.HIGHEST_PRECEDENCE)
        public class CorsFilterConfiguration {
        
          @Bean
          public CorsFilter corsFilter() {
              UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
              CorsConfiguration config = new CorsConfiguration();
              config.setAllowCredentials(true);
              config.addAllowedOrigin("*");
              config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
              config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
              source.registerCorsConfiguration("/**", config);
              return new CorsFilter(source);
          }
        }
        

        对我的 web.xml 进行修改,为所有 URL 添加新过滤器:

        <filter>
          <filter-name>corsFilter</filter-name>
          <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        </filter>
        <filter-mapping>
          <filter-name>corsFilter</filter-name>
          <url-pattern>/*</url-pattern>
        </filter-mapping>
        

        显然您可以相应地修改 cors 配置。

        【讨论】:

          【解决方案8】:

          我遇到了同样的问题,设置 ma​​xAge 属性后一切正常!

          @Bean
          public WebMvcConfigurer CORSConfigurer() {
              return new WebMvcConfigurer() {
                  @Override
                  public void addCorsMappings(CorsRegistry registry) {
                      registry.addMapping("/**")
                              .allowedOrigins("*")
                              .allowedHeaders("*")
                              .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                              .maxAge(-1)   // add maxAge
                              .allowCredentials(false);
                  }
              };
          }
          

          如果您检查 CrossOrigin 注释,则它具有分配给该属性的默认值

          /**
           * <p>By default this is set to {@code 1800} seconds (30 minutes).
           */
          long maxAge() default -1;
          

          【讨论】:

            【解决方案9】:

            我在使用 Spring mvc 应用程序(不是 Spring Boot)时遇到了同样的问题。 我可以解决问题的唯一方法是显式地将 cors 过滤器添加到 spring 安全过滤器链:

            public class MySecurityInitializer extends AbstractSecurityWebApplicationInitializer {
            
              protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
                final FilterRegistration.Dynamic corsFilter = servletContext.addFilter("corsFilter", corsFilter());
                corsFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
              }
            
              protected CorsFilter corsFilter() {
                UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                CorsConfiguration config = new CorsConfiguration();
                config.setAllowedOrigins(Arrays.asList(CrossOrigin.DEFAULT_ORIGINS));
                config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
                config.setAllowedHeaders(Arrays.asList(CrossOrigin.DEFAULT_ALLOWED_HEADERS));
                config.setAllowCredentials(CrossOrigin.DEFAULT_ALLOW_CREDENTIALS);
                config.setMaxAge(CrossOrigin.DEFAULT_MAX_AGE);
                source.registerCorsConfiguration("/**", config);
            
                return new CorsFilter(source);
              }
            
            }
            

            好运!

            【讨论】:

              【解决方案10】:

              我试图通过 WebMvcConfigurerAdapter 全局配置 CORS,并显示您的日志。 我找到了日志消息,但出现了类似的错误

              CORS 策略已阻止从源“某些源”访问“myurl”处的 XMLHttpRequest:对预检请求的响应未通过访问控制检查:没有“Access-Controll-Allow-Origin”标头在请求的资源。

              我的案例也擅长@CrossOrigin,但不擅长全局配置。 我希望这会有所帮助。

              原因是web.xml。

              1。 我有 但是 WebConfig 类不在“一些基础包”包中,它在上层包中。 我将 WebConfig 移动到“一些基本包”包和

              2。 我删除了 因为我已经在 WebConfig 类中有 @EnableWebMvc。

              有效。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2017-07-10
                • 2020-06-23
                • 2019-11-13
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2022-01-15
                相关资源
                最近更新 更多