目录
关于跨域
在说SpringBoot的cors之前,我们先来记录下关于跨域的一些基本知识。首先,什么是跨域?所谓跨域,即:由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域!
简单的理解,我请求A服务的页面,但是再页面中又有请求B服务的请求,这时候就存在跨域的问题。顺便在说一下我们在做vue单页应用时候的跨域。vue前台跑起来之后,其实通过webpack启动了一个nodejs服务,把我们的写的组件等代码打包后放到node服务器运行,我们在浏览器中请求的是node服务所在域,但是正常情况下我们和后台交互的时候,是需要再请求后台接口服务域,这就造成了跨域问题,即:页面资源请求的node服务域,数据请求的后台接口服务域。关于处理vue跨域请求的问题,之前一篇博客已经做了记录,这里不赘述,具体请点我。
跨域请求其实分为两种情况:
(1)简单请求
简单请求其实就是普通的POST、GET请求,并且不定义修改任何header信息,这种情况下就是简单请求,简单请求的特点是,前端可以直接直接发起请求,后端也可以正常的响应,但是如果后端没有修改response的header信息,前端浏览器会直接拦截后端的response,在console中报跨域错误。
但实际上,请求已经发送到后端,且后端也进行了正常的返回,在NetWork中可以直观的看到请求已经正常发送并返回。
(2)非简单请求
所谓非简单请求,就是发送了DELETE/PUT等请求,并且有自定义header,或者Content-Type是application/json类型的时候,就是非简单请求,对于非简单请求,浏览器默认会先发送一次OPTIONS请求进行“探路”,确认后端服务是否支持跨域访问,如果不支持,就直接停止该次请求。相对于简单请求而言,这种请求会在到达后台服务的默认过滤器的时候,就会被拦截到,因为默认情况下是不支持OPTIONS请求的,后台的web服务会直接返回告知前端不支持这种请求,当然在后端也看不到任何的业务请求日志打印。
关于简单请求和复杂请求的明细,参考这里。
SpringBoot中添加过滤器
直接上代码,如下:
public class CorsConfig {
private CorsConfiguration buildConfig(){
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*");//允许任何域名使用
corsConfiguration.addAllowedHeader("*");//允许任何请求头
corsConfiguration.addAllowedMethod("*");//允许任何类型请求
//--
corsConfiguration.setMaxAge(3600L);
return corsConfiguration;
}
//@Bean
public CorsFilter corsFilter(){
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**",buildConfig());
return new CorsFilter(source);
}
}
这里说一下,在网上大概搜一下,关于这一块的解决方案很多,主要的核心都是如下代码,没有设置setMaxAge的代码。
corsConfiguration.addAllowedOrigin("*");//允许任何域名使用
corsConfiguration.addAllowedHeader("*");//允许任何请求头
corsConfiguration.addAllowedMethod("*");//允许任何类型请求
这种方式是可以行的,但是具体到实际开发中,还有一个小情况,那就是对于非简单请求,每次都是请求两次,也就是说,每次都会发送探路的OPTIONS请求。
通过设置setMaxAge后,可以看到第一次会发送OPTIONS请求,但是后续的就不会再发送探路请求了,如果超过MaxAge后。
关于代理
在做VUE开发的时候,我们尝试使用了代理的方式解决跨域问题,需要说明的是,如果前端使用了代理方式解决跨域问题,那就完全是前端的处理方案,后端不需要做任何处理,也不需要进行cors的处理。
但是,如果后端按照上面的方式进行了cors设置,那么前端就不需要代理了,正常的跑就行!