跨域
需要先了解一个概念:
同源: 协议、域名、端口都相同。(ie浏览器没有将端口号纳入同源策略的检查)
非同源的限制:
- 无法读取非同源网页的 Cookie、LocalStorage 和 IndexedDB
- 无法接触非同源网页的 DOM无法向
- 非同源地址发送 AJAX 请求
跨域:当前页面访问另外一个不同源的url地址,就是跨域
同源策略是浏览器的安全功能。浏览器拦截的是客户端发出的请求回来的数据接收,即请求发送了,服务器响应了,但是无法被浏览器接收。
跨域解决方案:
跨域资源共享(CORS): 可以指定什么样的跨域请求可以被授权
- 普通跨域请求:只需服务器端设置Access-Control-Allow-Origin(允许被跨域访问的地址)
- 带cookie跨域请求:前后端都需要进行设置
三种跨域配置方式:
-
在类或者方法上加上@CrossOrigin(origins="http://localhost:8080")
springMVC的版本要在4.2或以上版本才支持@CrossOrigin
@RestController @CrossOrigin(origins="http://localhost:8080") public class HelloConstoller{ @CrossOrigin(origins="http://localhost:8080") // 在类和方法上都能使用 public String hello(){ return "hello"; } }
-
全局配置类实现:
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 所有接口都支持跨域
.allowedOrigins("http://localhost:8081") // 接受跨域源
.allowedHeaders("*") // 允许的请求头
.allowedMethods("*") // 允许的请求方法
.maxAge(30 * 1000);// 探测请求有效期 秒级
}
}
注意:put,post等一些方法,发送请求时,会先发送一个探测请求(method:options),判断该接口是否被允许,maxAge()方法就是设置探测请求的有效期,有效期内,不再发送探测请求
注意:若使用了Spring Security,还想指定配置需要手动启用
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors().and()...
}
}
-
基于过滤器对CORS的支持
@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; } }