一、什么是跨域请求
1、什么是跨域
浏览器同源策略 1995年,同源政策由 Netscape 公司引入浏览器。目前, 所有浏览器都实行这个政策。 最初,它的含义是指,A网页设置的 Cookie,B网页不能 打开,除非这两个网页"同源"。
所谓"同源"指的是"三个相同"
- 协议相同 比如都是http 或者https
- 域名相同 比如:www.sina.com.cn
- 端口相同 比如都是:80 或者8081
总结:
- 浏览器从1个域名的网页请求另1个域名的资源时,只要 以上3者任意1个不同,都称为跨域请求。
- 如果没有设置跨域请求,2个网页数据默认是用不通的,浏览器控制台会有跨域提示
No 'Access-Control-Allow-Origin' header is present on
the requestedresource. Origin 'null' is therefore not allowed access.
2、为什么要进行跨域
单体应用因为前后端都在一个容器,不存在跨域。但是前后端分离的互联网应用是 需要跨域请求的。因为前后端域名不一样,不符合同源要求。后端返回的数据,前端不 能直接使用。
二、跨域请求解决办法
- 使用JSONP
- http响应头配置允许跨域
- 程序代码中处理 SpringBoot 通过拦截器配置
下面使用第三种SpringBoot拦截器配置进行跨域请求
1、配置拦截器
/**
* 跨域拦截器的配置
*/
public class NorsInterceptor 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", "*");
// 如果当前请求中包含option请求 放行
if (HttpMethod.OPTIONS.equals(request.getMethod())){
return true;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
2、配置拦截路径(在InterceptorConfig进行放行)
(1)注入跨域拦截器属性
@Bean
NorsInterceptor getNorsInterceptor() {
return new NorsInterceptor();
}
(2)进行拦截器放行
// 跨域拦截器放在最上面
registry.addInterceptor(getNorsInterceptor())
.addPathPatterns("/**");
总体配置:
// 配置生效的拦截器
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
NorsInterceptor getNorsInterceptor() {
return new NorsInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 跨域拦截器放在最上面
registry.addInterceptor(getNorsInterceptor())
.addPathPatterns("/**");
}
}
三、测试跨域请求
获取到了response的跨域请求头