简介
跨域问题网上有很多种解决方法,但很多时候用的迷迷糊糊还经常不好使,这里我就给大家归纳总结一下。
关于跨域问题我就不介绍是什么了,相信愿意品读笔者这篇文章的应该都遇到过,想要了解的可以自行百度一下。
解决问题的说明
CORS跨域问题一般出现在本地测试时前后端分离上的,基本上前端报错信息这些的就稳了
SpringBoot上的跨域有着两种大体上的解决思路,笔者因为写了一个前端VUE后端Springboot的项目出现过这里令人头疼的问题,后来加入SpringCloudzuul之后便再次出现这个问题,于是有一个对CORS相对了解的判断,有需要的同学可以认真的看一下,也欢迎指正
一,Spring Boot在未安装zuul、NGINX等网关服务时
这里的报错就是单纯的微服务报错,只需要在每一个报错的微服务上加入相应的代码即可解决
1.添加@CrossOrigin(allowCredentials =“true”)
在Controller层上添加@CrossOrigin注解即可,但是这里要说明一下,因为SpringBoot2.0中springframework是springframework5以上的版本,源码发生了改变,所以需要加上一个这样的属性@CrossOrigin(allowCredentials ="true")
这里在多说几个属性@CrossOrigin(origins = "*",maxAge = 3600)
origin="*"
代表所有域名都可访问
maxAge
简单来说就是Cookie的有效期 单位秒
若maxAge是负数,则代表为临时Cookie,不会被持久化,Cookie信息保存在浏览器内存中,浏览器关闭Cookie就消失
2.添加CorsConfig配置文件
如果上面方法没有成功还可以加上这样的配置类,个人感觉这个还是比较靠谱的,而且也解决了跨域中的另一个坑,获取不到请求头的问题,这个后期笔者也打算在多写一期来介绍一下。
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* 解决跨域问题拦截器中获取不到token的问题
* @author a2417
*
*/
@Configuration
public class CorsConfig {
@Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
// 设置你要允许的网站域名,如果全允许则设为 *
config.addAllowedOrigin("http://localhost:8080");
// 如果要限制 HEADER 或 METHOD 请自行更改
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
// 这个顺序很重要哦,为避免麻烦请设置在最前
bean.setOrder(0);
return bean;
}
}
有以上这两项基本上就算是能解决单一微服务的跨域问题了!
二.SpringBoot 在使用SpringCloud zuul 之后
这里有一个坑,其实在zuul配置上解决跨域的问题并不难,只是这里有一个互斥的问题,如果你像上面把每个单一的微服务配置上解决跨域的问题之后,又将zuul网关也配置上解决跨域,那么浏览器上依然会报我最上面发的那张图片的CORS错误,所以并不是你的zuul防跨域代码配错了。解决方法是将每一个单一的微服务的防跨越代码注释掉或者直接删掉,只留下zuul的防跨越即可,这样即可解决这个问题。下面说一下zuul的解决跨域问题代码
1.配置yml文件
zuul:
sensitive-headers: Access-Control-Allow-Origin
ignored-headers: Access-Control-Allow-Credentials,Access-Control-Allow-Origin,Vary,X-Frame-Options,token
2.添加config文件
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @Author: www.fhadmin.org
* @Date: 2019/9/16
* @Description: 使用zuul解决请求跨域问题
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); // 允许cookies跨域
config.addAllowedOrigin("*");// #允许向该服务器提交请求的URI,*表示全部允许,在SpringMVC中,如果设成*,会自动转成当前请求头中的Origin
config.addAllowedHeader("*");// #允许访问的头信息,*表示全部
config.setMaxAge(18000L);// 预检请求的缓存时间(秒),即在这个时间段里,对于相同的跨域请求不会再预检了
config.addAllowedMethod("*");// 允许提交请求的方法,*表示全部允许
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
有这两步即可将zuul完美配置上,记得将通过zuul访问的各个微服务防跨域配置删掉,这样就不用担心跨域问了。