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

前端控制台报错: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. Spring Boot 轻量替代框架 Solon 1.3.18 发布

    Solon 是一个微型的Java开发框架.项目从2018年启动以来,参考过大量前人作品:历时两年,4000多次的commit:内核保持0.1m的身材,超高的跑分,良好的使用体验.支持:RPC.REST ...

  2. 批量实现SSH无密码登陆认证脚本

    批量实现SSH无密码登陆认证脚本 问题背景 使用为了让linux之间使用ssh不需要密码,可以采用了数字签名RSA或者DSA来完成.主要使用ssh-key-gen实现. 1.通过 ssh-key-ge ...

  3. C语言利用for循环打印菱形

    C语言利用for循环打印菱形(高度为奇数) 这次用的方法是上下部分分开打印,先打印上部分,再打印下部分. 先举个简单的例子打印,再改进代码,登堂入室从而理解. 例:打印一个高度(高度必须为奇数)为 5 ...

  4. python基础(补充):python三大器之装饰器

    函数作为返回值 高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回. 我们来实现一个可变参数的求和.通常情况下,求和的函数是这样定义的: def calc_sum(*args): i = ...

  5. linux中mysql连接不上,服务启动失败等问题解决

    confluence问题解决方式 1)针对confluence访问页面报500与连接失败等问题 首先我们登陆部署confluence的服器 10.15.4.115 2)重启mysql服务,发现重启失败 ...

  6. SAAS云平台搭建札记: (四) AntD For React使用react-router-dom路由接收不同参数页面不刷新的问题

    在.net开发员眼里,如果使用MVC,根据路由匹配原则,可以通过各种方式接收参数,比如 /Post/List/1, /Post/List/2,或者 /Post/List?id=1,/Post/List ...

  7. 概A第一章测试

    ·  问题 1√ 得 10 分,满分 10 分       A与B不能同时发生,表明A与B互不相容.               ·  问题 2× 得 10 分,满分 10 分       A与B互逆 ...

  8. 10.for循环

    for循环 语法: for(初始化; 布尔表达式; 更新) { //代码语句 } 初始化最先执行,可以声明一种类型,可初始化一个或多个循环控制变量,也可以是一个空语句. 布尔值判断,为 true 执行 ...

  9. php和mysql数据库防SQL注入的有效解决办法

    <?php$mysqli = new mysqli("localhost", "my_user", "my_password", &q ...

  10. 【VritualEnv】虚拟环境的介绍和基本使用

    一.virtualenv的介绍: 在python开发中,我们可能会遇到一种情况,就是当前的项目依赖的是某一个版本,但是另一个项目依赖的是另一个版本,这样就会造成依赖冲突,而virtualenv就是解决 ...