SpringBoot 配置CORS - Go语言中文社区

SpringBoot 配置CORS


前言:CORS相关介绍可以查看CORS ———— 跨域解决方案 ,这里记录下SpringBoot如何使用CORS解决跨域资源共享问题。以下使用的SpringBoot版本是 2.0.5.RELEASE。

 

一、介绍

Spring官方介绍,SpringMVC从4.2版本开始就支持CORS。在Spring中,使用@CrossOrigin注解,可以在controller方法中使用,而不要其他任何配置;或者在全局配置中,可以通过注册一个WebMvcConfigurer Bean,并使用addCorsMappings(CorsRegistry) 来定义。

SpringBoot 介绍 : https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/reference/htmlsingle/#boot-features-cors

Spring 4.2版本介绍:https://docs.spring.io/spring/docs/4.2.0.RELEASE/spring-framework-reference/htmlsingle/#cors

 

二、CrossOrigin注解

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CrossOrigin {

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	String[] DEFAULT_ORIGINS = { "*" };

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	String[] DEFAULT_ALLOWED_HEADERS = { "*" };

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	boolean DEFAULT_ALLOW_CREDENTIALS = false;

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	long DEFAULT_MAX_AGE = 1800;


	/**
	 * Alias for {@link #origins}.
	 */
	@AliasFor("origins")
	String[] value() default {};

	/**
	 * The list of allowed origins that be specific origins, e.g.
	 * {@code "http://domain1.com"}, or {@code "*"} for all origins.
	 * <p>A matched origin is listed in the {@code Access-Control-Allow-Origin}
	 * response header of preflight actual CORS requests.
	 * <p>By default all origins are allowed.
	 * <p><strong>Note:</strong> CORS checks use values from "Forwarded"
	 * (<a href="http://tools.ietf.org/html/rfc7239">RFC 7239</a>),
	 * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
	 * if present, in order to reflect the client-originated address.
	 * Consider using the {@code ForwardedHeaderFilter} in order to choose from a
	 * central place whether to extract and use, or to discard such headers.
	 * See the Spring Framework reference for more on this filter.
	 * @see #value
	 */
	@AliasFor("value")
	String[] origins() default {};

	/**
	 * The list of request headers that are permitted in actual requests,
	 * possibly {@code "*"}  to allow all headers.
	 * <p>Allowed headers are listed in the {@code Access-Control-Allow-Headers}
	 * response header of preflight requests.
	 * <p>A header name is not required to be listed if it is one of:
	 * {@code Cache-Control}, {@code Content-Language}, {@code Expires},
	 * {@code Last-Modified}, or {@code Pragma} as per the CORS spec.
	 * <p>By default all requested headers are allowed.
	 */
	String[] allowedHeaders() default {};

	/**
	 * The List of response headers that the user-agent will allow the client
	 * to access on an actual response, other than "simple" headers, i.e.
	 * {@code Cache-Control}, {@code Content-Language}, {@code Content-Type},
	 * {@code Expires}, {@code Last-Modified}, or {@code Pragma},
	 * <p>Exposed headers are listed in the {@code Access-Control-Expose-Headers}
	 * response header of actual CORS requests.
	 * <p>By default no headers are listed as exposed.
	 */
	String[] exposedHeaders() default {};

	/**
	 * The list of supported HTTP request methods.
	 * <p>By default the supported methods are the same as the ones to which a
	 * controller method is mapped.
	 */
	RequestMethod[] methods() default {};

	/**
	 * Whether the browser should send credentials, such as cookies along with
	 * cross domain requests, to the annotated endpoint. The configured value is
	 * set on the {@code Access-Control-Allow-Credentials} response header of
	 * preflight requests.
	 * <p><strong>NOTE:</strong> Be aware that this option establishes a high
	 * level of trust with the configured domains and also increases the surface
	 * attack of the web application by exposing sensitive user-specific
	 * information such as cookies and CSRF tokens.
	 * <p>By default this is not set in which case the
	 * {@code Access-Control-Allow-Credentials} header is also not set and
	 * credentials are therefore not allowed.
	 */
	String allowCredentials() default "";

	/**
	 * The maximum age (in seconds) of the cache duration for preflight responses.
	 * <p>This property controls the value of the {@code Access-Control-Max-Age}
	 * response header of preflight requests.
	 * <p>Setting this to a reasonable value can reduce the number of preflight
	 * request/response interactions required by the browser.
	 * A negative value means <em>undefined</em>.
	 * <p>By default this is set to {@code 1800} seconds (30 minutes).
	 */
	long maxAge() default -1;

}

 

三、具体使用

1、method配置

@CrossOrigin(origins = "http://localhost:8080", methods = RequestMethod.POST)
@RequestMapping(value = "/single", method = RequestMethod.POST)
public String single() {
    return "{"name":"single"}";
}

直接在方法级上添加@CrossOrigin注解启用CORS,默认情况下,允许@RequestMapping注释中所指定的所有的Origins和Methods。

 

2、controller配置

@CrossOrigin(origins = "http://localhost:8080", methods = { RequestMethod.GET})
@RestController()
@RequestMapping("/test")
public class TestController {

    @RequestMapping(value = "/common", method = RequestMethod.GET)
    public String common() {
        return "{"name":"common"}";
    }

    @RequestMapping("test")
    public String test() {
        return "test";
    }
    
    @RequestMapping(value = "other", method = RequestMethod.POST)
    public String other() {
        return "other";
    }
}

只需要在controller上添加@CrossOrigin注解启用CORS。此时该controller里的common,test两个方法都支持跨域,但是other不支持,因为method不支持。

 

3、controller和method共存

@CrossOrigin(methods = RequestMethod.GET)
@RestController()
@RequestMapping("/test")
public class TestController {

    /**
     * 
     * @return
     * @Description: 单接口支持跨域
     */
    @CrossOrigin(origins = "http://localhost:8080", methods = RequestMethod.POST)
    @RequestMapping(value = "/single", method = RequestMethod.POST)
    public String single() {
        return "{"name":"single"}";
    }

    /**
     * 
     * @return
     * @Description: 该controller下的公共支持跨域
     */
    @RequestMapping(value = "/common", method = RequestMethod.GET)
    public String common() {
        return "{"name":"common"}";
    }

    @RequestMapping("test")
    public String test() {
        return "test";
    }
}

controller和method同时开启注解,但是实际以method的为主。

 

4、全局配置

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter{

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

 
}

只需要添加一个配置文件,重写addCorsMappings方法,但是,在2.0.5版本中, WebMvcConfigurerAdapter已被废弃。

可以通过注册一个WebMvcConfigurer bean:

@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer configurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
            }

        };
    }

}

 这里默认所有方法都跨域,并且GET, POST,HEAD是被允许的,如果需要自定义,只需要配置即可:

比如:

@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer configurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/common/**")
                    .allowedOrigins("http://localhost:8080")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTION")
                    .maxAge(100);
            }

        };
    }

}

当全局配置,controller和method都存在时,以最小力度为准。

 

5、全局过滤器配置

    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Bean
    public FilterRegistrationBean filter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOrigin("http://localhost:8080");
        configuration.addAllowedMethod("GET");
        configuration.addAllowedMethod("POST");
        configuration.addAllowedMethod("OPTION");
        configuration.addAllowedMethod("PUT");
        source.registerCorsConfiguration("/**", configuration);
        return new FilterRegistrationBean(new CorsFilter(source));

    }

跟4类似。。。。

 

总结:SpringBoot配置CORS非常方便,也很灵活,比自己用servlet定义快捷方便,最主要的是,即使使用简单请求,跨域请求失败,也不会走到实际的业务流程中。 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/nainaiqiuwencun/article/details/83029770
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-08 17:07:42
  • 阅读 ( 1093 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢