一、跨域(CORS)反对:
Spring Framework 4.2 GA为CORS提供了第一类反对,使您比通常的基于过滤器的解决方案更容易和更弱小地配置它。所以springMVC的版本要在4.2或以上版本才反对@CrossOrigin
二、应用办法:
1、controller配置CORS
1.1、controller办法的CORS配置,您能够向@RequestMapping注解处理程序办法增加一个@CrossOrigin注解,以便启用CORS(默认状况下,@CrossOrigin容许在@RequestMapping注解中指定的所有源和HTTP办法):
@RestController
@RequestMapping("/account") public class AccountController {
@CrossOrigin@GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ...
}
@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ...
}
}
其中@CrossOrigin中的2个参数:
origins : 容许可拜访的域列表
maxAge:筹备响应前的缓存继续的最大工夫(以秒为单位)。
1.2、为整个controller启用@CrossOrigin
@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account") public class AccountController {
@GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ...
}
@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ...
}
}
在这个例子中,对于retrieve()和remove()解决办法都启用了跨域反对,还能够看到如何应用@CrossOrigin属性定制CORS配置。
1.3、同时应用controller和办法级别的CORS配置,Spring将合并两个正文属性以创立合并的CORS配置。
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account") public class AccountController {
@CrossOrigin(origins = "http://domain2.com")@GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ...
}
@DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ...
}
}
1.4、如果您正在应用Spring Security,请确保在Spring安全级别启用CORS,并容许它利用Spring MVC级别定义的配置。
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override protected void configure(HttpSecurity http) throws Exception { http.cors().and()...}
}
2、全局CORS配置
除了细粒度、基于正文的配置之外,您还可能须要定义一些全局CORS配置。这相似于应用筛选器,但能够申明为Spring MVC并联合细粒度@CrossOrigin配置。默认状况下,所有origins and GET, HEAD and POST methods是容许的。
JavaConfig
使整个应用程序的CORS简化为:
@Configuration
@EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter {
@Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**");}
}
如果您正在应用Spring Boot,倡议将WebMvcConfigurer bean申明如下:
@Configuration public class MyConfiguration {
@Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } };}
}
您能够轻松地更改任何属性,以及仅将此CORS配置利用到特定的门路模式:
@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);
}
如果您正在应用Spring Security,请确保在Spring安全级别启用CORS,并容许它利用Spring MVC级别定义的配置。
3、XML命名空间
还能够将CORS与MVC XML命名空间配置。
a、如果整个我的项目所有办法都能够拜访,则能够这样配置;此最小XML配置使CORS在/**门路模式具备与JavaConfig雷同的缺省属性:
<mvc:cors>
<mvc:mapping path="/**" />
</mvc:cors>
其中 示意匹配到下一层; 示意前面不论有多少层,都能匹配。*
如:
<mvc:cors>
<mvc:mapping path="/api/*"/>
</mvc:cors>
这个能够匹配到的门路有:
/api/aaa
/api/bbbb
不能匹配的:
/api/aaa/bbb
因为* 只能匹配到下一层门路,如果想前面不论多少层都能够匹配,配置如下:
<mvc:cors>
<mvc:mapping path="/api/**"/>
</mvc:cors>
注:其实就是一个()变成两个(*)
b、也能够用定制属性申明几个CORS映射:
<mvc:cors>
<mvc:mapping path="/api/**" allowed-origins="http://domain1.com, http://domain2.com" allowed-methods="GET, PUT" allowed-headers="header1, header2, header3" exposed-headers="header1, header2" allow-credentials="false" max-age="123" /><mvc:mapping path="/resources/**" allowed-origins="http://domain1.com" />
</mvc:cors>
申请门路有/api/,办法示例如下:
@RequestMapping("/api/crossDomain")
@ResponseBody public String crossDomain(HttpServletRequest req, HttpServletResponse res, String name){
…… ……
}
c、如果应用Spring Security,不要遗记在Spring安全级别启用CORS:
<http>
<!-- Default to Spring MVC's CORS configuration --><cors /> ... </http>
4、How does it work?
CORS申请(包含预选的带有选项办法)被主动发送到注册的各种HandlerMapping 。它们解决CORS筹备申请并拦挡CORS简略和理论申请,这得益于CorsProcessor实现(默认状况下默认DefaultCorsProcessor处理器),以便增加相干的CORS响应头(如Access-Control-Allow-Origin)。 CorsConfiguration 容许您指定CORS申请应该如何解决:容许origins, headers, methods等。
a、AbstractHandlerMapping#setCorsConfiguration() 容许指定一个映射,其中有几个CorsConfiguration 映射在门路模式上,比方/api/**。
b、子类能够通过重写AbstractHandlerMapping类的getCorsConfiguration(Object, HttpServletRequest)办法来提供本人的CorsConfiguration。
c、处理程序能够实现 CorsConfigurationSource接口(如ResourceHttpRequestHandler),以便为每个申请提供一个CorsConfiguration。
5、基于过滤器的CORS反对
作为上述其余办法的代替,Spring框架还提供了CorsFilter。在这种状况下,不必应用@CrossOrigin或 WebMvcConfigurer#addCorsMappings(CorsRegistry),例如,能够在Spring Boot应用程序中申明如下的过滤器:
@Configuration public class MyConfiguration {
@Bean public FilterRegistrationBean corsFilter() { UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); CorsConfiguration config = new CorsConfiguration(); config.setAllowCredentials(true); config.addAllowedOrigin("http://domain1.com"); config.addAllowedHeader("*"); config.addAllowedMethod("*"); source.registerCorsConfiguration("/**", config); FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source)); bean.setOrder(0); return bean;}
}
三、spring注解@CrossOrigin不起作用的起因
1、是springMVC的版本要在4.2或以上版本才反对@CrossOrigin
2、非@CrossOrigin没有解决跨域申请问题,而是不正确的申请导致无奈失去预期的响应,导致浏览器端提醒跨域问题。
3、在Controller注解上方增加@CrossOrigin注解后,依然呈现跨域问题,解决方案之一就是:
在@RequestMapping注解中没有指定Get、Post形式,具体指定后,问题解决。
相似代码如下:
@CrossOrigin
@RestController public class person{
@RequestMapping(method = RequestMethod.GET) public String add() { // 若干代码
}
}
四、参考文章:
1、官网文档https://spring.io/blog/2015/0...
2、http://fanshuyao.iteye.com/bl...
2、https://blog.csdn.net/taiyang...
3、https://blog.csdn.net/snowin1...