一、跨域 (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…