SpringMVC
中处理跨域资源共享(CORS)
(学习笔记2020.3.26)
前言:
什么是跨域资源共享?
CORS
是一种允许当前域的资源(比如html/js/web service)被其他域的脚本请求访问的机制,通常由于同域安全策略浏览器会禁止这种跨域请求。 (详细介绍) 所谓跨域指的是域名不同或者端口不同或者协议不同,资源会发起一个跨域 HTTP 请求。站点 http://domain-a.com 的某 HTML 页面访问http://domain-b.com/test网站资源就会存在跨域问题。从4.2版本开始,
Spring MVC
支持CORS。在Spring Boot应用程序中将控制器方法CORS配置与@CrossOrigin
注释一起使用不需要任何特定的配置。 可以通过使用自定义方法注册bean 来定义全局CORS配置。当
html
页面里面发起跨域请求时候,浏览器控制台就会报以下错误:
Access to XMLHttpRequest at 'http://zhihao.com/list' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
1. 使用注解@CrossOrigin
解决
1.1 @CrossOrigin
介绍:
@CrossOrigin
在类和方法级别上使用。如果找不到匹配的
CORS
配置,则请求将被拒绝。
属性 | 含义 |
---|---|
value | 指定所支持域的集合,* 表示所有域都支持,默认值为* 。这些值对应HTTP请求头中的Access-Control-Allow-Origin |
origins | 同value |
allowedHeaders | 允许请求头中的header,默认都支持 |
exposedHeaders | 响应头中允许访问的header,默认为空 |
methods | 支持请求的方法,比如GET ,POST ,PUT 等,默认和Controller中的方法上标注的一致。 |
allowCredentials | 是否允许cookie随请求发送,使用时必须指定具体的域, 默认情况下不会启用。 |
maxAge | 预请求的结果的有效期,默认30分钟 |
1.2 使用在类级别上
并且被所有方法继承
@Controller
@CrossOrigin
@RequestMapping("/test")
public class TestController {
@ResponseBody
@GetMapping("/list")
public List<User> findAll(){
List<User> list = userService.findAll();
System.out.println(list);
return list;
}
}
使用在类上,如果没有指定属性,将使用
@CrossOrigin
默认值。
1.3 使用在ap
i方法上
只有这个
api
方法生效可以跨域
@GetMapping("/list")
@CrossOrigin(origins = {"http://zhihao.com"},methods = RequestMethod.GET)
public List<User> findAll(){
List<User> list = userService.findAll();
System.out.println(list);
return list;
}
我们这里可以指定属性, 放行来源
http://zhihao.com
的跨域请求,并且只能是GET`请求。
2. 配置类全局配置
创建一个配置
WebConfig
类,实现WebMvcConfigurer 接口
,并重写addCorsMappings
方法
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") //所有请求
.allowedOrigins("*") //允许的来源 `*`所有
.allowedMethods("GET","PUT")
.maxAge(3600); //预请求的结果被客户端缓存有效期
//.allowCredentials(true) 是否允许cookie随请求发送
//.allowedHeaders() 允许的请求头部
}
}
2.1 XML
全局配置
要在XML名称空间中启用CORS,可以使用``元素,如以下示例所示:
<mvc:cors>
<mvc:mapping path="/api/**"
allowed-origins="https://domain1.com, https://domain2.com"
allowed-methods="GET, PUT"
allowed-headers="header1, header2, header3"
exposed-headers="header1, header2" allow-credentials="true"
max-age="123" />
<mvc:mapping path="/resources/**"
allowed-origins="https://domain1.com" />
</mvc:cors>
3. CORS
过滤器
您可以通过内置的
CorsFilter
应用CORS
支持。如果您尝试将CorsFilter与Spring Security一起使用,请记住Spring Security内置了对CORS的支持。
要配置过滤器,请将CorsConfigurationSource传递给其构造函数,如以下示例所示:
@Bean
public FilterRegistrationBean corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config);
//此类提供setOrder方法,可以为CorsFilter设置排序值
FilterRegistrationBean registrationBean = new FilterRegistrationBean(new CorsFilter(source));
//设置优先级
registrationBean.setOrder(0);
return registrationBean;
}
1