Java Spring全局CORS配置不起作用,但控制器级配置起作用

Java Spring全局CORS配置不起作用,但控制器级配置起作用,java,spring-mvc,http-headers,cors,cross-domain,Java,Spring Mvc,Http Headers,Cors,Cross Domain,我正试图通过如下所示的WebMVCConfigureAdapter全局配置CORS。为了进行测试,我正在通过一个小型节点应用程序访问API端点,该应用程序是我为模拟外部服务而创建的。当我尝试这种方法时,响应不包含正确的头,并且失败 XMLHttpRequest cannot load http://localhost:8080/api/query/1121. No 'Access-Control-Allow-Origin' header is present on the requested r

我正试图通过如下所示的
WebMVCConfigureAdapter
全局配置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

要使全局配置正常工作,我缺少什么(请按照此处的说明进行操作)。我觉得我缺少了一些简单的东西,因为注释控制器工作得很好。

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

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

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

您没有在其中声明方法,默认情况下,该方法是只接受get方法。
尝试注册表中的
allowedMethods(“*”)

为了使全局CORS配置工作,客户端必须在选项请求中添加这两个标题

Origin: http://host.com
Access-Control-Request-Method: POST
然而,@CrossOrigin注释只需要“Origin”标题。

您的客户端可能添加了“Origin”头,但缺少“Access Control Request Method”……这就是为什么它适用于@CrossOrigin,但不适用于全局配置

我也面临类似的问题。我将WebMVCConfigureAdapter更改为WebMvcConfigurationSupport,它开始工作。


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

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

  • 如果allowCredentials为true,则allowCredentials不能为*。这在Mozilla.org上有记录

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


  • 我有一个类似的问题,所有方法似乎都不起作用(除了为每个控制器使用
    @CrossOrigin
    注释)。我遵循上面的解决方案,并在对Spring框架内部进行了一些调试之后—以下是对我有效的方法(Spring Boot 2.0.6+Spring Framework 5.0.10):


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

    我刚刚遇到了完全相同的问题,这个线程中的任何解决方案都不起作用。我通过以下方法解决了这个问题:

    新的配置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);
      }
    }
    
    修改my 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>
    
    
    克斯菲尔特
    org.springframework.web.filter.DelegatingFilterProxy
    克斯菲尔特
    /*
    

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

    我也面临同样的问题,在设置了maxAge属性之后,一切都开始正常工作了

    @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);
            }
        };
    }
    
    如果选中交叉原点注释,则会为该属性指定一个默认值

    /**
     * <p>By default this is set to {@code 1800} seconds (30 minutes).
     */
    long maxAge() default -1;
    
    /**
    *默认设置为{@code 1800}秒(30分钟)。
    */
    long maxAge()默认值为-1;
    
    我在使用Spring mvc应用程序(不是Spring Boot)时也遇到过同样的问题。 我能解决这个问题的唯一方法是显式地将cors过滤器添加到spring security过滤器链:

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

    祝你好运

    我试图通过WebMVCConfigureAdapter全局配置CORS,您的日志显示了这一点。 我发现了一条日志消息,但出现了如下错误

    CORS策略已阻止从源站“某些源站”访问“myurl”处的XMLHttpRequest:对飞行前请求的响应未通过访问控制检查:请求的资源上没有“访问控制允许源站”标头

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

    原因是web.xml

    一,。 我有 但是WebConfig类不在“某个基本包”包中,它在上面的包中。 我将WebConfig移到“一些基本包”包中,然后

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


    它可以工作。

    谢谢您的回复,我也尝试了
    “/api/query/**”
    ,但没有成功。最初,我甚至用registry.addMapping(“/**”)
    实现了一个“hello world”类型的实现,但这并没有什么区别。。我是否必须以某种方式指定它位于端口8080上?我甚至不知道。。。它看起来应该可以正常工作。AllowedOrigination(“*”)。AllowedHeader(“*”)在全局配置中是冗余的。你明白了吗?我也有这个问题。我尝试了下面的答案,但对我不起作用…@威尔我和你在同一条船上,但设法找到了工作。看看我在这里的回答:我在使用POST方法时面临同样的问题。通过添加allowedmethods解决了这个问题。我发现
    拒绝设置不安全的头文件“访问控制请求方法”
    ,chrome`83.0.4103.61(官方版本)(64位)`如果是在web浏览器中运行的代码,客户端无法这样做。
    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);
      }
    
    }