什么是跨域?
简单来说就是当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
浏览器为了页面安全,设置了同源策略:即本域脚本只能读写本域内的资源,而无法访问其它域的资源。所谓同源就是“协议+域名+端口”三者相同,当在一个站点内访问非该同源的资源,浏览器就会报跨域错误。,当在一个站点内访问非该同源的资源,浏览器就会报跨域错误。浏览器的两种同源策略会造成跨域问题:
- DOM同源策略。禁止对不同源的页面的DOM进行操作,主要包括iframe、canvas之类的。不同源的iframe禁止数据交互的,含有不同源数据的canvas会受到污染而无法进行操作。
- XmlHttpRequest同源策略。简单来说就禁止不同源的AJAX请求,主要用来防止CSRF攻击。
同源策略是浏览器的行为,所以不要说为什么我自己使用postman测试接口时却可以。
**
拦截器解决跨域问题
废话不多说,直接上代码
public class CorsInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//表示接受任意域名的请求,也可以指定域名
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
//该字段可选,是个布尔值,表示是否可以携带cookie
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "*");
//这里可以不加,但是其他语言开发的话记得处理options请求
/**
* 非简单请求是对那种对服务器有特殊要求的请求,
* 比如请求方式是PUT或者DELETE,或者Content-Type字段类型是application/json。
* 都会在正式通信之前,增加一次HTTP请求,称之为预检。浏览器会先询问服务器,当前网页所在域名是否在服务器的许可名单之中,
* 服务器允许之后,浏览器会发出正式的XMLHttpRequest请求
*/
if(HttpMethod.OPTIONS.toString().equals(request.getMethod())){
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
注册拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
CorsInterceptor corsInterceptor(){
return new CorsInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
//拦截全部
registry.addInterceptor(corsInterceptor()).addPathPatterns("/**");
WebMvcConfigurer.super.addInterceptors(registry);
}
}