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

前端控制台报错: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;
}

完美解决!

Spring Boot 允许跨域设置失败的问题深究的更多相关文章

  1. 玩转spring boot——ajax跨域

    前言  java语言在多数时,会作为一个后端语言,为前端的php,node.js等提供API接口.前端通过ajax请求去调用java的API服务.今天以node.js为例,介绍两种跨域方式:Cross ...

  2. spring boot 解决 跨域 的两种方法 -- 前后端分离

    1.前言 以前做项目 ,基本上是使用 MVC 模式 ,使得视图与模型绑定 ,前后端地址与端口都一样 , 但是现在有些需求 ,需要暴露给外网访问 ,那么这就出现了个跨域问题 ,与同源原则冲突, 造成访问 ...

  3. Spring/Spring MVC/Spring Boot实现跨域

    说明:Spring MVC和Spring Boot其实用的都是同一套. CORS介绍请看这里:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Acc ...

  4. Spring Boot实现跨域(转)

    一.方法: 服务端设置Respone Header头中Access-Control-Allow-Origin 配合前台使用jsonp 继承WebMvcConfigurerAdapter 添加配置类 二 ...

  5. 踩坑录- Spring Boot - CORS 跨域 - 浏览器同源策略

    1.解决办法,创建一个过滤器,处理所有response响应头 import java.io.IOException; import javax.servlet.Filter; import javax ...

  6. Spring Boot + Vue 跨域请求问题

    使用Spring Boot + Vue 做前后端分离项目搭建,实现登录时,出现跨域请求 Access to XMLHttpRequest at 'http://localhost/open/login ...

  7. 【Spring Boot】Spring Boot之跨域解决方案

    一.什么是跨域 跨域,指的是从一个域名去请求另外一个域名的资源.即跨域名请求!跨域时,浏览器不能执行其他域名网站的脚本,是由浏览器的同源策略造成的,是浏览器施加的安全限制. 跨域的严格一点来讲就是只要 ...

  8. spring boot 解决跨域访问

    package com.newings.disaster.shelters.configuration; import org.springframework.context.annotation.B ...

  9. spring mvc \ spring boot 允许跨域请求 配置类

    用@Component 注释下,随便放个地方就可以了 package com.chinaws.wsarchivesserver.core.config; import org.springframew ...

随机推荐

  1. SQL 存储过程里调用另一个存储过程

    由于创建了一个存储过程,并且要在另一个存储过程里调用这个存储过程所以在网上找了一下相关的代码,现在总结一下,防止以后还会用到 由于这次我写的存储过程只需要返回一个求和的结果,所以我使用了output ...

  2. Cloudreve 自建云盘实践,我说了没人能限得了我的容量和速度!

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 为啥要用自建网盘,市面上的云盘不香了? 每一个用户需求的背后都是因为有场景存在,而这 ...

  3. Python数据分析入门(十六):设置可视化图表的信息

    现在我们添加图后,没有指定x轴代表什么,y轴代表什么,以及这个图的标题是什么.因此以下我们通过一些属性来设置一下. 设置线条样式: 使用plot方法:plot方法就是用来绘制线条的,因此可以在绘制的时 ...

  4. Centos下搭建LAMP+PHP

    Centos下搭建LAMP+PHP LAMP是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写: Linux,操作系统 Apache,网页服务器 MariaDB或MySQL,数据库管 ...

  5. TypeScript 入门自学笔记 — 类型断言(二)

    码文不易,转载请带上本文链接,感谢~ https://www.cnblogs.com/echoyya/p/14558034.html 目录 码文不易,转载请带上本文链接,感谢~ https://www ...

  6. Pandas的loc,iloc与ix的用法及区别

    1.先来谈一谈loc,loc这个方法就是你有啥我就用啥,你没有的我不用,pandas对象的index,columns有什么,pd.loc[index,column],index就是pd.index的其 ...

  7. 聊一聊Jmeter的参数化

    背景 前面一篇讲了 JMeter 的一个最简单的例子,这篇聊一下 JMeter 的参数化. 在开始之前先来一个单元测试的例子,感受一下参数化. 上面是一个用 xUnit 写的单元测试,这个单元测试就是 ...

  8. Property Distribution(DFS)

    Property Distribution タナカ氏が HW アールの果樹園を残して亡くなりました.果樹園は東西南北方向に H×W の区画に分けられ.区画ごとにリンゴ.カキ.ミカンが植えられています. ...

  9. 在 Y 分钟内学会 Python

    在 Y 分钟内学会 Python 这是翻译, 原文地址: Learn Python in Y Minutes 在 90 年代初, Python 由 Guido van Rossum 创造, 现在, 它 ...

  10. Unittest单元测试框架——BeautifulReport测试报告和Yagmail自动发送邮件

    一.前言 之前在做appium自动化的时候,已经提到过unittest框架的基本概念.用例执行,以及BeautifulReport测试报告的简单使用了(地址:https://www.cnblogs.c ...