Springboot拦截器中跨域失效的问题、同一个接口传入参数不同,一个成功,一个有跨域问题、拦截器和@CrossOrigin和@Controller
Springboot拦截器中跨域失效的问题
一、概述
1、具体场景
起因:
- 同一个接口,传入不同参数进行值的修改时,一个成功,另一个竟然失败,而且是跨域问题
- 拦截器内的request参数调用getHeader方法时,获取不到前端设置的请求头,且浏览器显示有,但是后端输出后只有对于的key,而且key变成了
access-control-request-headers的value
同一个接口不同参数错误展示:
前端代码展示:

浏览器请求头显示:
后端获取request的header参数显示:
全是null

输出headers:
{sec-fetch-mode=cors, referer=http://localhost:8080/, sec-fetch-site=cross-site, accept-language=zh-CN,zh;q=0.9, origin=http://localhost:8080, access-control-request-method=POST, accept=*/*, host=127.0.0.1:8099, access-control-request-headers=content-type,headeruserid,headerusertoken, connection=keep-alive, accept-encoding=gzip, deflate, br, user-agent=Mozilla/5.0 (Linux; Android 8.0.0; SM-G955U Build/R16NW) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Mobile Safari/537.36, sec-fetch-dest=empty}
变成了这样:access-control-request-headers=content-type,headeruserid,headerusertoken,
2、背景
前端:
- 是个uniapp项目,只会调,不会写,未设置跨域
后端:
- spring boot项目
- 后端使用了
@CrossOrigin(origins = "*"),进行了简单的跨域设置 - 后端使用了拦截器进行拦截认证
3、尝试改bug
发现前端的参数key,浏览器的参数key和后端的参数key大小写不一致:
- 修改了多次,且尝试了多次,无效果
String userId = request.getHeader("headerUserId");
String userId2 = request.getHeader("HeaderUserId");
String userId3 = request.getHeader("Headeruserid");

尝试前端添加跨域:
- 统一设置跨域请求头,不会,只会小改
- 前端添加:Access-Control-Allow-Origin: *,无效,后面认真看才发现这是响应头,不是请求头,sha呗了
尝试后端的拦截器内添加@CrossOrigin(origins = “*”)、具体拦截方法内给响应参数添加响应头:
- 无效
重启前端项目、清除浏览器缓存、清除idea缓存、rebuild项目、重新运行:
- 无效
二、解决办法
试了很多方法,慢慢的就定位了问题:
- 前端设置的请求头,浏览器可以接收,而且具体显示,那就不是前端的问题
- 后端试了很多次,拦截器获取的request header 的key和value还是null
- 如果取消拦截器,正常可以获取
- 那么可能是拦截器的问题,我的
@CrossOrigin(origins = "*")加在我的接口上,但是拦截器先执行,如果没用通过那么直接返回,根本到不了我的接口,也就到不了我接口上的@CrossOrigin(origins = "*"),那就没用跨域了 - 但是我尝试再拦截器内的方法中手动给response响应添加跨域的代码,如下,但是还是无效
// 支持跨域
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods",
"GET,POST,PUT,DELETE,OPTIONS");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Headers", "Content-Type,X-Token");
response.setHeader("Access-Control-Allow-Credentials", "true");
后面查询跨域的请求流程:
跨域请求的流程通常分为两个阶段:预检请求(Preflight Request)和实际请求。以下是跨域请求的一般流程:
-
预检请求阶段:
- 当浏览器检测到跨域请求时(例如请求方法不是简单请求方法、请求包含自定义的请求头等),会首先发送一个预检请求(OPTIONS请求)给服务器。
- 预检请求的目的是询问服务器是否允许实际请求中包含特定的自定义请求头字段和请求方法。
- 预检请求会包含一些特定的请求头,如
Access-Control-Request-Method和Access-Control-Request-Headers,用来询问服务器的允许范围。 - 服务器收到预检请求后,根据预检请求中的信息判断是否允许实际请求,然后发送适当的CORS响应头给浏览器。
-
实际请求阶段:
- 如果预检请求得到了服务器的允许(即服务器返回了合适的CORS响应头),浏览器将发送实际的请求给服务器。
- 实际请求中包含了正常的请求方法(例如GET、POST、PUT等)、请求头和请求体等信息。
- 服务器收到实际请求后,会处理请求并返回相应的响应给浏览器。
下图展示了跨域请求的流程:
+-------------+ +-------------+| Browser | | Server |+-------------+ +-------------+| || 1. 发送预检请求 |+----------------------->|| || 2. 接收预检响应 ||<-----------------------+| || 3. 发送实际请求 |+----------------------->|| || 4. 接收实际响应 ||<-----------------------+
总的来说,跨域请求的流程就是浏览器先发送预检请求询问服务器是否允许跨域请求,然后根据服务器的响应决定是否发送实际请求。如果预检请求得到了服务器的允许,浏览器才会发送实际的请求。
跟着这个OPTIONS请求查找:
发现,只需要我把这个请求过滤掉即可,让它可以实际请求,使得我的自定义请求头 - 特定的请求头(access-control-request-headers=content-type,headeruserid,headerusertoken)可以接收到我就可以进行判断了。
if ("OPTIONS".equals(request.getMethod().toUpperCase())) {return true;
}
有效果,解决了。

三、拓展
此处是使用的@CrossOrigin(origins = "*")注解同时过滤掉OPTIONS请求实现了跨域
还可以通过只设置一个跨域过滤器解决跨域问题:
下列方法转载于博客园作者小泉哥:
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;/*** 全局跨域配置类* 跨域请求的配置,允许所有来源的跨域请求* * 跨域请求流程:* 1. 浏览器发送预检请求(OPTIONS请求)给服务器,询问是否允许实际请求中包含特定的自定义请求头字段和请求方法。* 2. 服务器根据预检请求的信息判断是否允许实际请求,发送适当的CORS响应头给浏览器。* 3. 如果预检请求得到了服务器的允许,浏览器发送实际的请求给服务器。* 4. 服务器收到实际请求后,处理请求并返回相应的响应给浏览器。* * 注:当设置allowCredentials为true时,Access-Control-Allow-Origin响应头不能使用通配符"*",而是必须明确指定允许的来源。* * @author red-velvet* @since 2024/2/8*/
@Configuration
public class GlobalCorsConfig {/*** 配置CorsFilter* @return CorsFilter*/@Beanpublic CorsFilter corsFilter() {// 创建CorsConfiguration对象,配置CORS跨域规则CorsConfiguration config = new CorsConfiguration();// 允许所有来源的跨域请求config.addAllowedOrigin("*");// 允许携带凭据(例如Cookie)config.setAllowCredentials(false);// 允许所有请求方法的跨域请求config.addAllowedMethod("*");// 允许所有请求头的跨域请求config.addAllowedHeader("*");// 创建UrlBasedCorsConfigurationSource对象,注册CORS配置UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();configSource.registerCorsConfiguration("/**", config);// 创建CorsFilter对象,传入配置源return new CorsFilter(configSource);}
}
dCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource();configSource.registerCorsConfiguration("/**", config);// 创建CorsFilter对象,传入配置源return new CorsFilter(configSource);}
}
相关文章:
Springboot拦截器中跨域失效的问题、同一个接口传入参数不同,一个成功,一个有跨域问题、拦截器和@CrossOrigin和@Controller
Springboot拦截器中跨域失效的问题 一、概述 1、具体场景 起因: 同一个接口,传入不同参数进行值的修改时,一个成功,另一个竟然失败,而且是跨域问题拦截器内的request参数调用getHeader方法时,获取不到前端…...
WordPress如何自建txt文本经典语录并随机显示一句话经典语录?
前面跟大家分享的『WordPress集成一言(Hitokoto)API经典语句功能』一文中就提供有自创API,其中懿古今顶部左上角显示的经典语录用的就是自建一个txt文本文件,然后再在前端网页指定位置随机显示语录。具体操作方法如下:…...
Java中JVM常用参数配置(提供配置示例)
目录 前言一、内存参数配置二、垃圾收集器配置三、GC策略配置3.1、基础通用配置3.2、Parallel 和 Parallel Old 常用参数配置3.3、CMS 常用参数配置3.4、G1 常用参数配置 四、GC日志配置五、dump 日志参数配置5.1、OutOfMemory异常时生成dump文件5.2、发生Full GC时生成dump文件…...
图论与图数据应用综述:从基础概念到知识图谱与图智能
目录 前言1 图论基础概念1.1 节点度1.2 度分布1.3 邻接矩阵 2 探索图的高级概念2.1 最短路径的关键性2.2 图的直径与平均路径的意义2.3 循环与路径类型的多样性 3 深入探讨图的广泛应用领域3.1 知识图谱的知识管理3.2 图智能在复杂决策中的应用3.3 图数据挖掘与分析的多领域应用…...
知识碎片-SpringBoot统一返回结果和捕获异常
统一返回结果 定义统一返回结果类ResultResponse定义新注解ResponseResult来标记需要拦截的方法或类添加RestControllerAdvice注解,实现ResponseBodyAdvice接口,重写support, beforeBodyWrite方法 统一结果类ResultResponse Setter Getter public cla…...
Open-FWI代码解析(1)
目录 1. dataset文件 1.1初始化网络 1.2load_every函数 1.3 getitem函数 1.4测试函数 2. transforms文件 2.1裁切函数和翻转函数 2.2上\下采样函数 2.3加入随机因子的上\下采样函数 2.4填充函数 2.5标准图像函数 2.6标准化函数 2.7归一化函数 2.8反归一化 2.9添加噪声的函数 …...
移动机器人激光SLAM导航(五):Cartographer SLAM 篇
参考 Cartographer 官方文档Cartographer 从入门到精通 1. Cartographer 安装 1.1 前置条件 推荐在刚装好的 Ubuntu 16.04 或 Ubuntu 18.04 上进行编译ROS 安装:ROS学习1:ROS概述与环境搭建 1.2 依赖库安装 资源下载完解压并执行以下指令 https://pa…...
第四篇【传奇开心果微博系列】Python微项目技术点案例示例:美女颜值判官
传奇开心果微博系列 系列微博目录Python微项目技术点案例示例系列 微博目录一、微项目目标二、雏形示例代码三、扩展思路四、添加不同类型的美女示例代码五、增加难度等级示例代码六、添加特殊道具示例代码七、设计关卡系统示例代码八、添加音效和背景音乐示例代码九、多人游戏…...
Python学习之路-初识爬虫:requests
Python学习之路-初识爬虫:requests requests的作用 作用:发送网络请求,返回响应数据 中文文档 : http://docs.python-requests.org/zh_CN/latest/index.html 为什么学requests而不是urllib requests的底层实现就是urllibrequests在pytho…...
Linux 常用的命令
① 基本命令 uname -m 显示机器的处理器架构uname -r 显示正在使用的内核版本dmidecode -q 显示硬件系统部件(SMBIOS / DMI) hdparm -i /dev/hda 罗列一个磁盘的架构特性hdparm -tT /dev/sda 在磁盘上执行测试性读取操作系统信息arch 显示机器的处理器架构uname -m 显示机器的处…...
假期作业 10
1.整理磁盘操作的完整流程,如何接入虚拟机,是否成功识别,对磁盘分区工具的使用,格式化,挂载以及取消挂载 U盘接入虚拟机 在虚拟机--->可移动设备--->找到U盘---->连接 检测U盘是否被虚拟机识别 ls /dev/s…...
【洛谷 P3367】【模板】并查集 题解(并查集+路径压缩)
【模板】并查集 题目描述 如题,现在有一个并查集,你需要完成合并和查询操作。 输入格式 第一行包含两个整数 N , M N,M N,M ,表示共有 N N N 个元素和 M M M 个操作。 接下来 M M M 行,每行包含三个整数 Z i , X i , Y i Z_i,X_i,Y…...
Netty应用(一) 之 NIO概念 基本编程
目录 第一章 概念引入 1.分布式概念引入 第二章 Netty基础 - NIO 1.引言 1.1 什么是Netty? 1.2 为什么要学习Netty? 2.NIO编程 2.1 传统网络通信中开发方式及问题(BIO) 2.1.1 多线程版网络编程 2.1.2 线程池版的网络编程…...
tkinter-TinUI-xml实战(10)展示画廊
tkinter-TinUI-xml实战(10)展示画廊 引言声明文件结构核心代码主界面统一展示控件控件展示界面单一展示已有展示多类展示 最终效果在这里插入图片描述  ………… 结语 引言…...
LeetCode二叉树的垂序遍历
题目描述 给你二叉树的根结点 root ,请你设计算法计算二叉树的 垂序遍历 序列。 对位于 (row, col) 的每个结点而言,其左右子结点分别位于 (row 1, col - 1) 和 (row 1, col 1) 。树的根结点位于 (0, 0) 。 二叉树的 垂序遍历 从最左边的列开始直到…...
[linux c]linux do_div() 函数用法
linux do_div() 函数用法 do_div() 是一个 Linux 内核中的宏,用于执行 64 位整数的除法操作,并将结果存储在给定的变量中,同时将余数存储在另一个变量中。这个宏通常用于内核编程中,特别是在处理大整数和性能敏感的场合。 函数原…...
Python学习之路-爬虫提高:常见的反爬手段和解决思路
Python学习之路-爬虫提高:常见的反爬手段和解决思路 常见的反爬手段和解决思路 明确反反爬的主要思路 反反爬的主要思路就是:尽可能的去模拟浏览器,浏览器在如何操作,代码中就如何去实现。浏览器先请求了地址url1,保留了cookie…...
python_numpy库_ndarray的聚合操作、矩阵操作等
一、ndarray的聚合操作 1、求和np.sum() import numpy as np n np.arange(10) print(n) s np.sum(n) print(s) n np.random.randint(0,10,size(3,5)) print(n) s1 np.sum(n) print(s1) #全部数加起来 s2 np.sum(n,axis0) print(s2) #表示每一列的多行求和 …...
python-自动化篇-终极工具-用GUI自动控制键盘和鼠标-pyautogui
文章目录 用GUI自动控制键盘和鼠标pyautogui 模块鼠标屏幕位置——移动地图——pyautogui.size鼠标位置——自身定位——pyautogui.position()移动鼠标——pyautogui.moveTo拖动鼠标滚动鼠标 键盘按下键盘释放键盘 开始与结束通过注销关闭所有程序 用GUI自动控制键盘和鼠标 在…...
面试:大数据和深度学习之间的关系是什么?
大数据与深度学习之间存在着紧密的相互关系,它们在当今技术发展中相辅相成。 大数据的定义与特点:大数据指的是规模(数据量)、多样性(数据类型)和速度(数据生成及处理速度)都超出了传统数据处理软件和硬件能力范围的数据集。它具有四个主要特点,通常被称…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
大话软工笔记—需求分析概述
需求分析,就是要对需求调研收集到的资料信息逐个地进行拆分、研究,从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要,后续设计的依据主要来自于需求分析的成果,包括: 项目的目的…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
WordPress插件:AI多语言写作与智能配图、免费AI模型、SEO文章生成
厌倦手动写WordPress文章?AI自动生成,效率提升10倍! 支持多语言、自动配图、定时发布,让内容创作更轻松! AI内容生成 → 不想每天写文章?AI一键生成高质量内容!多语言支持 → 跨境电商必备&am…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...


