Spring CORS 不存在“Access-Control-Allow-Origin”标头

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/35091524/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 00:57:09  来源:igfitidea点击:

Spring CORS No 'Access-Control-Allow-Origin' header is present

springspring-mvccors

提问by Ian Mc

I am getting the following problem after porting web.xml to java config

将 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.

Based on a few Spring references, the following attempt has been tried:

根据一些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);
    }

}

The values chosen were taken from a working web.xml filter:

选择的值取自工作的 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>

Any ideas why the Spring java config approach is not working like the web.xml file did?

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

回答by Omkar

Change the CorsMapping from registry.addMapping("/*")to registry.addMapping("/**")in addCorsMappingsmethod.

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

Check out this Spring CORS Documentation.

查看此 Spring CORS文档

From the documentation-

文档中-

Enabling CORS for the whole application is as simple as:

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

You can easily change any properties, as well as only apply this CORS configuration to a specific path pattern:

您可以轻松更改任何属性,也可以仅将此 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

控制器方法 CORS 配置

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

To enable CORS for the whole controller -

为整个控制器启用 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) {
        // ...
    }
}

You can even use both controller-level and method-level CORS configurations; Spring will then combine attributes from both annotations to create merged CORS configuration.

您甚至可以同时使用控制器级别和方法级别的 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) {
        // ...
    }
}

回答by reversebind

Helpful tip - if you're using Spring data rest you need a different approach.

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

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

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

回答by Sabarish

We had the same issue and we resolved it using Spring's XML configuration as below:

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

Add this in your context xml file

将此添加到您的上下文 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>

回答by matsev

If you are using Spring Security ver >= 4.2 you can use Spring Security's native support instead of including Apache's:

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

The example above was copied from a Spring blog postin which you also can find information about how to configure CORS on a controller, specific controller methods, etc. Moreover, there is also XML configuration examples as well as Spring Boot integration.

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

回答by Shane

Following on Omar's answer, I created a new class file in my REST API project called WebConfig.javawith this configuration:

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

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

This allows any origin to access the API and applies it to all controllers in the Spring project.

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

回答by Shihe Zhang

Omkar's answer is quite comprehensive.

Omkar 的回答非常全面。

But some part of the Global config part has changed.

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

According to the spring boot 2.0.2.RELEASE reference

根据spring boot 2.0.2.RELEASE参考

As of version 4.2, Spring MVC supports CORS. Using controller method CORS configuration with @CrossOrigin annotations in your Spring Boot application does not require any specific configuration. Global CORS configuration can be defined by registering a WebMvcConfigurer bean with a customized addCorsMappings(CorsRegistry) method, as shown in the following example:

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

Most answer in this post using WebMvcConfigurerAdapter, however

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

The type WebMvcConfigurerAdapter is deprecated

不推荐使用 WebMvcConfigurerAdapter 类型

Since Spring 5 you just need to implement the interface WebMvcConfigurer:

public class MvcConfig implements WebMvcConfigurer {

This is because Java 8 introduced default methods on interfaces which cover the functionality of the WebMvcConfigurerAdapter class

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

public class MvcConfig implements WebMvcConfigurer {

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

回答by Rumid

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

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

I had configured cors properly, but what was missing in webflux in RouterFuncion was accept and contenttype headers APPLICATION_JSONlike in this piece of code:

我已经正确配置了 cors,但是在 RouterFuncion 中的 webflux 中缺少的是 accept 和 contenttype 标头APPLICATION_JSON就像在这段代码中一样:

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

回答by womd

as @Geoffrey pointed out, with spring security, you need a different approach as described here: Spring Boot Security CORS

正如@Geoffrey 指出的那样,对于 Spring Security,您需要一种不同的方法,如下所述: Spring Boot Security CORS

回答by Anshul Kabra

For some reason, if still somebody not able to bypass CORS, write the header which browser wants to access your request.

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

Add this bean inside your configuration file.

在您的配置文件中添加这个 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", "*"));


        }
    };
}

This way we can tell the browser we are allowing cross-origin from all origin. if you want to restrict from specific path then change the "*" to {'http://localhost:3000',""}.

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

Helpfull reference to understand this behaviour https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example

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

回答by NafazBenzema

I have found the solution in spring boot by using @CrossOriginannotation.

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

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

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