Spring CORS没有'Access-Control-Allow-Origin'标题

Ian*_* Mc 68 spring spring-mvc cors

将web.xml移植到java配置后,我遇到了以下问题

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.
Run Code Online (Sandbox Code Playgroud)

基于一些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);
    }

}
Run Code Online (Sandbox Code Playgroud)

选择的值取自工作的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>
Run Code Online (Sandbox Code Playgroud)

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

Omk*_*kar 92

将CorsMapping更改registry.addMapping("/*")registry.addMapping("/**")in addCorsMappings方法.

查看Spring CORS 文档.

文档 -

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以轻松更改任何属性,并仅将此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);
    }
}
Run Code Online (Sandbox Code Playgroud)

控制器方法CORS配置

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

为整个控制器启用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) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

您甚至可以使用控制器级和方法级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) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 为整个应用程序启用CORS对我不起作用. (22认同)
  • 都2020年了,spring boot注解还是不行。 (6认同)
  • 使用`addCorsMapping`对我来说不起作用,很想说这是因为春天的安全性...,但是根据建议添加`corsConfigurationSource` bean [here](https://docs.spring.io/spring-security/ site/docs/current/reference/html/cors.html)解决了我的问题. (2认同)
  • 你真是一个救星。我正在使用 Spring 4.2 并尝试了无数其他替代方案,但在我尝试 addCorsMappings 重写方法之前,它们都不起作用。添加标准 CORS 标头以及 Access-Control-Allow-Headers 可能有帮助,也可能没有帮助 (2认同)

Sab*_*ish 8

我们遇到了同样的问题,我们使用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>
Run Code Online (Sandbox Code Playgroud)


Shi*_*ang 8

Omkar 的回答非常全面。

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

根据spring boot 2.0.2.RELEASE参考

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

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)

大多数的答案在这篇文章中使用WebMvcConfigurerAdapter,但是

不推荐使用 WebMvcConfigurerAdapter 类型

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

public class MvcConfig implements WebMvcConfigurer {
Run Code Online (Sandbox Code Playgroud)

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


rev*_*ind 7

有用的提示 - 如果你正在使用Spring数据休息,你需要一个不同的方法.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

 @Override
 public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getCorsRegistry().addMapping("/**")
            .allowedOrigins("http://localhost:9000");
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢你的帖子。当我注意到您的帖子说 Spring Data REST 使用不同的方法时,我有点失去希望。现在完全适合我! (3认同)
  • `RepositoryRestConfigurerAdapter` 已弃用。只需直接实现“RepositoryRestConfigurer”即可。 (2认同)

Sha*_*ane 7

按照 Omar 的回答,我在WebConfig.java使用此配置调用的 REST API 项目中创建了一个新类文件:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedOrigins("*");
  }
} 
Run Code Online (Sandbox Code Playgroud)

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


mat*_*sev 6

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
Run Code Online (Sandbox Code Playgroud)

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