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


84

将web.xml移植到Java配置后出现以下问题

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配置方法无法像web.xml文件那样工作?

Answers:


112

将CorsMapping从更改registry.addMapping("/*")registry.addMapping("/**")inaddCorsMappings方法。

请查阅此Spring CORS文档

文档中-

为整个应用程序启用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);
    }
}

控制器方法CORS配置

@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) {
        // ...
    }
}

36
对整个应用程序启用CORS对我不起作用。
Dimitri Kopriwa '16

4
使用addCorsMapping对我来说不起作用,试图说这是由于Spring安全性的缘故...,但是corsConfigurationSource这里的建议添加bean解决了我的问题。
杰弗里

1
同样也不要忘记允许所有客户端使用registry.addMapping(“ / **”)。allowedOrigins(“ *”); spring.io/guides/gs/rest-service-cors
SpaceDev公司

1
您是真正的救星。我使用的是Spring 4.2,并尝试了无数其他替代方法,直到我尝试了addCorsMappings替代方法,它们都无法使用。可能会或可能不会有所帮助的是添加了标准CORS标头以及Access-Control-Allow-Headers
Vyrnach

2
它的2020和Spring Boot注释仍然不起作用。
程序员

14

有用的提示-如果您使用的是Spring数据其余部分,则需要使用其他方法。

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

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

3
感谢这篇文章。当我注意到您的帖子说Spring Data REST使用另一种方法时,我有点松散的希望。现在完全为我工作!
乔纳森·克雷格

2
RepositoryRestConfigurerAdapter不推荐使用。只是RepositoryRestConfigurer直接实现。
Gustavo Rodrigues

9

我们遇到了同样的问题,我们使用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>

4

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

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


4

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

  @Override
  public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**").allowedOrigins("*");
  }
} 

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


4

奥姆卡的答案很全面。

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

根据Spring Boot 2.0.2.RELEASE参考

从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/**");
            }
        };
    }
}

本文中大多数答案使用WebMvcConfigurerAdapter,但是

WebMvcConfigurerAdapter类型已弃用

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

public class MvcConfig implements WebMvcConfigurer {

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


1

公共类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");
            }
        };
    }

}

0

我也有类似的消息 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);
}


0

出于某种原因,如果仍然有人无法绕过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


0

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

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.