赞
踩
1、官方文档: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework.
2、 http://fanshuyao.iteye.com/blog/2384189.
3、 https://blog.csdn.net/taiyangnimeide/article/details/78305131.
4、 https://blog.csdn.net/snowin1994/article/details/53035433.
5、 https://blog.csdn.net/qq_15006743/article/details/78841780.
6、 https://blog.csdn.net/qq_18671415/article/details/109275495.
出于安全原因,浏览器禁止Ajax调用驻留在当前原点之外的资源。例如,当你在一个标签中检查你的银行账户时,你可以在另一个选项卡上拥有EVILL网站。来自EVILL的脚本不能够对你的银行API做出Ajax请求(从你的帐户中取出钱!)使用您的凭据。
跨源资源共享(CORS)是由大多数浏览器实现的W3C规范,允许您灵活地指定什么样的跨域请求被授权,而不是使用一些不太安全和不太强大的策略,如IFRAME或JSONP。
CORS简介
CORS:全称"跨域资源共享"(Cross-origin resource sharing)。
CORS需要浏览器和服务器同时支持,才可以实现跨域请求,目前几乎所有浏览器都支持CORS,IE则不能低于IE10。CORS的整个过程都由浏览器自动完成,前端无需做任何设置,跟平时发送ajax请求并无差异。so,实现CORS的关键在于服务器,只要服务器实现CORS接口,就可以实现跨域通信。
请求类型:
CORS分为简单请求和非简单请求(需预检请求)两类
@CrossOrigin使用
可以简单理解,如果前端端口是localhost:8080,后端端口是localhost:9090,controller配置了@CrossOrigin (没有添加其他参数,默认如何端口都可以访问)可以实现跨越访问,也可以使用其他配置类实现跨域访问。
作用: 在controller上添加@CrossOrigin注解用来开启跨域请求,让其他域的请求可以访问该controller,否则所有其他域的访问会全部被拒绝。
Spring Framework 4.2 GA为CORS提供了第一类支持,使您比通常的基于过滤器的解决方案更容易和更强大地配置它。所以springMVC的版本要在4.2或以上版本才支持@CrossOrigin
1、controller配置CORS
1.1、controller方法的CORS配置
你可以向@RequestMapping注解处理程序方法添加一个@CrossOrigin注解,以便启用CORS(默认情况下,@CrossOrigin允许在@RequestMapping注解中指定的所有源和HTTP方法):
@RestController
public class DeliveryController {
@CrossOrigin
@PostMapping("/delivery/addRecord")
public CommonResult<Integer> add(@RequestBody DeliveryRecord deliveryRecord) {
// ...
}
@GetMapping("/delivery/checkRecord")
public CommonResult<DeliveryRecord> checkRecord(@RequestParam Integer deliveryId) {
// ...
}
}
其中@CrossOrigin中的可以填2个参数:
1.2、为整个controller启用@CrossOrigin
@CrossOrigin(origins = "http://127.0.0.1:8888/api/", maxAge = 3600)
@RestController
public class DeliveryController {
@PostMapping("/delivery/addRecord")
public CommonResult<Integer> add(@RequestBody DeliveryRecord deliveryRecord) {
// ...
}
}
在这个例子中,对于retrieve()和remove()处理方法都启用了跨域支持,还可以看到如何使用@CrossOrigin属性定制CORS配置。
1.3、同时使用controller和方法级别的CORS配置
Spring将合并两个注释属性以创建合并的CORS配置。
@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class DeliveryController { @CrossOrigin(origins = "http://127.0.0.1:8888/api/") @PostMapping("/delivery/addRecord") public CommonResult<Integer> add(@RequestBody DeliveryRecord deliveryRecord) { // ... } @GetMapping("/delivery/checkRecord") public CommonResult<DeliveryRecord> checkRecord(@RequestParam Integer deliveryId) { // ... } }
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是允许的。
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
/** * 跨域配置 */ @Configuration public class CorsConfig implements WebMvcConfigurer { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"). allowedOrigins("https://www.dustyblog.cn"). //允许跨域的域名,可以用*表示允许任何域名使用 allowedMethods("*"). //允许任何方法(post、get等) allowedHeaders("*"). //允许任何请求头 allowCredentials(true). //带上cookie信息 //maxAge(3600)表明在3600秒内,不需要再发送预检验请求,可以缓存该结果 exposedHeaders(HttpHeaders.SET_COOKIE).maxAge(3600L); } }; } }
@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);
}
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; } }
@CrossOrigin
@RestController
public class person{
@RequestMapping(method = RequestMethod.GET)
public String add() {
// 若干代码
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。