首页 技术 正文
技术 2022年11月19日
0 收藏 851 点赞 3,701 浏览 2780 个字

在公司开发过程中,一个前后端分离的项目遇见了跨域的问题。

前端控制台报错:No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

从经验得知:spring boot解决跨域问题。两种解决方法:

1、重写 WebMvcConfigurer 类,并注入到spring容器中:

@Configuration
public class CustomCorsConfiguration implements WebMvcConfigurer { @Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
.allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
"Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
.allowCredentials(true).maxAge(3600);
}
}

这个底层我猜想是一种拦截器,他的优先级在过滤器之后。也就是说执行完过滤器,才会执行这个拦截器。

2、在@Configuration中,注入CorsFilter:

    @Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig());
return new CorsFilter(source);
} private CorsConfiguration corsConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 请求常用的三种配置,*代表允许所有,也可以自定义属性(比如 header 只能带什么,只能是 post 方式等)
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setMaxAge(3600L);
return corsConfiguration;
}

这个底层就是过滤器,想要获得服务器的跨域允许,必须经过此CorsFilter

不过,在尝试了两种方法发现,why?我的项目还是报错:No ‘Access-Control-Allow-Origin’ header is present on the requested resource.

在使用第二种方法,并经过调试后发现了问题,CorsFilter 的执行顺序在token过滤器的后面!

这时候再来了解下跨域的原理,详见 http://www.ruanyifeng.com/blog/2016/04/cors.html

我这边前端是属于跨域中的非简单请求,他的过程是:在前端真正发送请求api接口的http时,会发出一个类似于嗅探的假请求给服务器,这个假请求会从服务器携带信息,告知页面是否允许页面跨域访问,如果允许,则发出真正的http,如果不,浏览器控制台直接报错。

我这个项目的问题就出在这。如果这个嗅探没到达CorsFilter,就被服务器拦截下来了,那么他得到的信息肯定是 不允许跨域访问 ! 我们的嗅探就是被项目中的jwt过滤器拦截下来了,因为我在项目中的设定是每个请求必须携带jwt的token,否则被拦截下来,而嗅探是一种浏览器生成的简单请求,肯定不携带jwt token,因此被拦截下来了,也就没法到达CorsFilter,就没法获得跨域的许可。所以在使用百度的第二种方法就失败了!

那么第一种百度的方法失败的原因呢?更简单了!因为第一种底层是拦截器(WebMvcConfigurer),他的执行优先级在过滤器之后,所以嗅探的http在到这个拦截器的时候,早就被jwt过滤器挡下来了,因此提示跨域失败!

听了上述分析,是否解决思路已经有了呢?对,只要我们的嗅探http到达CorsFilter过滤器或者拦截器(WebMvcConfigurer)就行了,但是我们的jwt过滤必须得要,所以我的解决方法是,修改CorsFilter的优先级

    @Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig());
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
//*****这里设置了优先级*****
     bean.setOrder(1);
return bean;
} private CorsConfiguration corsConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 请求常用的三种配置,*代表允许所有,也可以自定义属性(比如 header 只能带什么,只能是 post 方式等)
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
corsConfiguration.setAllowCredentials(true);
corsConfiguration.setMaxAge(3600L);
return corsConfiguration;
}

完美解决!

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,020
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,513
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,359
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,142
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,772
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,850