javaEE WebServlet、SpringWebMVC、SpringBoot实现跨域访问的4种方式及优先级,nginx配置跨域
文章目录
- 1. 前置知识
- 2. 原理和解决方案总结
- 2.1. 跨域不通过原理流程图
- 2.2. 实现原理:添加以下http响应头
- 2.3. 四种跨域实现方式及优先级(从高到低)
- 3. 具体实现代码
- 3.1. 跨域全局配置方式-Filter(全适用)
- 3.2. 跨域全局配置方式-SpringMvc
- 3.3. 跨域单个配置方式-WebServlet
- 3.4. 跨域单个配置方式-SpringMvc
- 4.非java实现方式
- 4.1. nginx代理
- 9. 参考文章
1. 前置知识
- 【尚硅谷】【视频】【B站】禹神:一小时彻底搞懂跨域&解决方案
- 【尚硅谷】【笔记】【CSDN】禹神:彻底搞懂前端跨域&解决方案
2. 原理和解决方案总结
2.1. 跨域不通过原理流程图

2.2. 实现原理:添加以下http响应头
| 序号 | 响应头 | 含义 |
|---|---|---|
| 1 | Access-Control-Allow-Origin | 允许的源 |
| 2 | Access-Control-Allow-Methods | 允许的方法 |
| 3 | Access-Control-Allow-Headers | 允许的自定义头 |
| 4 | Access-Control-Max-Age | 预检请求的结果缓存时间(可选) |

2.3. 四种跨域实现方式及优先级(从高到低)
- 跨域全局配置方式-Filter(全适用): 重写 Filter.doFilter(),设置 res.setHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
- 跨域全局配置方式-SpringMvc : 重写 WebMvcConfigurer.addCorsMappings(),设置 registry.addMapping(“/**”).allowedOrigins(“*”)等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
- 跨域单个配置方式-WebServlet: 设置 res.addHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
- 跨域单个配置方式-SpringMvc : 添加 @CrossOrigin注解,设置origins等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
3. 具体实现代码
- gitee源码
3.1. 跨域全局配置方式-Filter(全适用)
- 重写
Filter.doFilter(),设置res.setHeader("Access-Control-Allow-Origin", "*")等响应头参数
/** 1.跨域全局配置方式-Filter(全适用) */
@Configuration
public class CorsFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletResponse res = (HttpServletResponse) response;res.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin")); //【跨域配置】[必需] 允许请求源 :默认值 无,配置"*"允许所有。// 如果是复杂请求的预检请求(判断逻辑同SpringMvc),设置以下响应头,且没必要执行其它过滤器链 chain.doFilter(request, response);if (req.getMethod().equalsIgnoreCase("OPTIONS") && !ObjUtil.hasNull(req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"))) {res.setHeader("Access-Control-Allow-Methods", req.getHeader("Access-Control-Request-Method")); //【跨域配置】[有复杂请求方法时必需] 允许请求方法:默认值 无,配置 "*",允许所有res.setHeader("Access-Control-Allow-Headers", req.getHeader("Access-Control-Request-Headers")); //【跨域配置】[有复杂请求头时必需] 允许请求头 : 默认值 无,配置 "*",允许所有res.setHeader("Access-Control-Max-Age", "5"); //【跨域配置】[非必需] 预检缓存时长: 默认值 依赖客户端。EDGE浏览器默认值为3秒。【注意浏览器不要禁用缓存,否则不生效】return;}}
}
3.2. 跨域全局配置方式-SpringMvc
- 重写 WebMvcConfigurer.addCorsMappings(),设置 registry.addMapping(“/**”).allowedOrigins(“*”)等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
/** 2.跨域全局配置方式-SpringMvc */
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 适配@RequestMapping。 (例如:/ajax/** 开头的)// 下面几个参数,不配置,会使用默认值。origins 和 originPatterns取并集.allowedOrigins("*") //【跨域配置】[必需] 允许请求源:默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", ).allowedOriginPatterns("*") //【跨域配置】[必需] 允许请求源:默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", ).allowedMethods("*") //【跨域配置】[有复杂请求方法时必需] 允许请求方法:默认值为GET,POST,HEAD。相当于res.setHeader("Access-Control-Allow-Methods", ).allowedHeaders("*") //【跨域配置】[有复杂请求头时必需] 允许请求头 :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Headers", ).maxAge(1800); //【跨域配置】[非必需] 预检缓存时长:默认值 1800秒。小于等于0时缓存无效【注意浏览器不要禁用缓存,否则不生效】。相当于res.setHeader("Access-Control-Max-Age", )}
}
3.3. 跨域单个配置方式-WebServlet
- 设置 res.addHeader(“Access-Control-Allow-Origin”, “*”) 等响应头参数
/** 3.跨域单个配置方式-WebServlet */
@Slf4j
@WebServlet(name = "ajax", value = {"/ajax/WebServlet", "/ajax/WebServlet/"})
public class AjaxWebServlet extends HttpServlet {@Overrideprotected void service(HttpServletRequest req, HttpServletResponse res) throws IOException {log.warn("method==【{}】, name==【{}】, header.origin==【{}】, Access-Control-Request-Method==【{}】, Access-Control-Request-Headers==【{}】", req.getMethod(), req.getParameter("name"), req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"), req.getHeader("Access-Control-Request-Headers"));res.setHeader("Access-Control-Allow-Origin", "*"); //【跨域配置】[必需] 允许请求源 :默认值 无,配置"*"允许所有。res.setHeader("Access-Control-Allow-Methods", "*"); //【跨域配置】[有复杂请求方法时必需] 允许请求方法:默认值 无,配置 "*",允许所有res.setHeader("Access-Control-Allow-Headers", "*"); //【跨域配置】[有复杂请求头时必需] 允许请求头 : 默认值 无,配置 "*",允许所有res.setHeader("Access-Control-Max-Age", "1800"); //【跨域配置】[非必需] 预检缓存时长: 默认值 依赖客户端。EDGE浏览器默认值为3秒。【注意浏览器不要禁用缓存,否则不生效】res.getWriter().write(DateUtil.now() + "@" + req.getMethod());}
}
3.4. 跨域单个配置方式-SpringMvc
- 添加 @CrossOrigin注解,设置origins等响应头参数(只对SpringMvc写法生效,对原生Servlet不生效)
/* 4.跨域单个配置方式-SpringMvc */
@Slf4j
@RestController
@RequestMapping("/ajax")
public class AjaxController {@CrossOrigin(// origins 和 originPatterns取并集。【注意】此处配置与下面的res.setHeader()功能相同,优先级较低。二选其一即可origins = {"*"}, //【跨域配置】[必需] 允许请求源 :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", )originPatterns = {"*"}, //【跨域配置】[必需] 允许请求源 :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Origin", )methods = {}, //【跨域配置】[有复杂请求方法时必需] 允许请求方法:默认值为(优先以@RequestMapping的method属性为准,如果没有指定则默认为"GET,POST,HEAD)。相当于res.setHeader("Access-Control-Allow-Methods", )allowedHeaders = {"*"}, //【跨域配置】[有复杂请求头时必需] 允许请求头 :默认值为"*",即允许所有。相当于res.setHeader("Access-Control-Allow-Headers", )maxAge = 1800 //【跨域配置】[非必需] 预检缓存时长:默认值 1800秒。小于等于0时缓存无效【注意浏览器不要禁用缓存,否则不生效】 。相当于res.setHeader("Access-Control-Max-Age", ))@RequestMapping(value = "/CrossOrigin", method = {RequestMethod.GET, RequestMethod.PUT})@SneakyThrowsvoid ajax(HttpServletRequest req, HttpServletResponse res) {log.warn("method==【{}】, name==【{}】, header.origin==【{}】, Access-Control-Request-Method==【{}】, Access-Control-Request-Headers==【{}】", req.getMethod(), req.getParameter("name"), req.getHeader("Origin"), req.getHeader("Access-Control-Request-Method"), req.getHeader("Access-Control-Request-Headers"));res.getWriter().write(DateUtil.now() + "@" + req.getMethod());}
}
4.非java实现方式
4.1. nginx代理
- 优点:不用侵入java代码
- 配置nginx反向代理。在配置文件
nginx.conf的http中添加一个server - 将
AJAX请求通过nginx转发。本例中,将AJAX请求发给58080端口,然后转发给8080端口
server {listen 58080;server_name localhost;location / {proxy_pass http://localhost:8080;# 增加响应头add_header Access-Control-Allow-Origin "*"; # 【跨域配置】[必需] 允许请求源 :默认值 无,配置"*"允许所有。if ($request_method = 'OPTIONS') { # 如果是复杂请求的预检请求(参考SpringMvc,最好同时判断请求头Origin、Access-Control-Request-Method都不为null,略),设置以下响应头,且没必要透传,直接返回add_header Access-Control-Allow-Origin "*"; # 【跨域配置】[必需] 允许请求源 :默认值 无,配置"*"允许所有。add_header Access-Control-Allow-Methods "*"; # 【跨域配置】[有复杂请求方法时必需] 允许请求方法:默认值 无,配置 "*",允许所有add_header Access-Control-Allow-Headers "*"; # 【跨域配置】[有复杂请求头时必需] 允许请求头 : 默认值 无,配置 "*",允许所有add_header Access-Control-Max-Age "5"; # 【跨域配置】[非必需] 预检缓存时长: 默认值 依赖客户端。EDGE浏览器默认值为3秒。【注意浏览器不要禁用缓存,否则不生效】return 204;}}
}
9. 参考文章
- @CrossOrigin详细参数说明
- SpringBoot处理跨域请求的四种方法
相关文章:
javaEE WebServlet、SpringWebMVC、SpringBoot实现跨域访问的4种方式及优先级,nginx配置跨域
文章目录 1. 前置知识2. 原理和解决方案总结2.1. 跨域不通过原理流程图2.2. 实现原理:添加以下http响应头2.3. 四种跨域实现方式及优先级(从高到低) 3. 具体实现代码3.1. 跨域全局配置方式-Filter(全适用)3.2. 跨域全局配置方式-SpringMvc3.3…...
深入理解JavaScript性能优化:从基础到高级
引言 在当今快速发展的Web世界中,性能已经成为衡量应用质量的关键指标。随着Web应用复杂度的不断提升,JavaScript作为前端开发的核心语言,其性能优化变得尤为重要。本文旨在全面深入地探讨JavaScript性能优化的各个方面,从基础概念到高级技巧,帮助开发者构建高效、流畅的Web应用…...
java+springboot实现定时任务
由于是初级程序员,基于注解的形式实现了一个简单的定时任务; 1. 使用Scheduled注解 Spring的Scheduled注解是一种非常简单和便捷的实现定时任务的方式。通过在方法上添加Scheduled注解,我们可以指定方法在特定的时间间隔或固定的时间点执行…...
1.3 数据库的发展历史与演变
欢迎来到我的博客,很高兴能够在这里和您见面!欢迎订阅相关专栏: 工💗重💗hao💗:野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典:收集整理全网各大IT互联网公司技术、项目、HR面试真题.…...
The field file exceeds its maximum permitted size of 1048576 bytes
场景: 再系统后台上传解析对账文件时大小超过1M就会报错 分析: 排查错误时了解MultipartFile默认上传大小就是1M,但是发现项目配置文件配置了上传大小100M,但是这个大小没有生效 因为项目启动并没有使用到这个配置大小并把他应用到file配置里面,经过测试发现只需要增加配置…...
【Es】python es操作
表 因为es是集群所以es_hosts是列表 from elasticsearch import Elasticsearch ES_HOSTS ["127.0.0.1:9200"] ES_HTTP_AUTH "******************"# 连接Es es Elasticsearch(hostsES_HOSTS ,http_authES_HTTP_AUTH ,maxsize60,timeout30,max_retries3…...
吃透前端文件上传与文件相关操作 多文件上传 大文件切片上传 拖拽上传 后续还会更新 断点续传等等
最近在学文件上传的操作,所以想把学习到东西写成一文章 这片文章是我以小白视角 慢慢学习并熟悉前端文件相关操作的流程总结出来的 前端文件上传 我首先想到是 <input type"file">**选择文件**</input>如果我们想限制上传文件的格式,大小或进行裁剪分片…...
用python制作88键赛博钢琴(能用鼠标键盘进行弹奏)
用python制作88键赛博钢琴 前言 恭喜这位博主终于想起了自己的账号密码! 时光荏苒,转眼间已逾一年未曾在此留下墨香。尽管这一年间,博主投身于无尽的忙碌与挑战之中,但令人欣慰的是,那份初心与热情似乎并未因岁月的流…...
zdpgo_gin_login 框架20240815更新,增加注册路由的功能,一个方法自动拥有注册和登录两个API接口
zdpgo_gin_login 适配gin框架的登录注册功能组件,通过本框架轻松拥有登录注册相关的API接口 特性: 自动生成注册接口,具备密码加密的功能自动生成登录接口,具备JWT Token生成的功能 安装 go get github.com/zhangdapeng520/z…...
搭配Intel第13代酷睿处理器
高性能内存硬盘这么买 intel第13代酷睿已经于2022年10月底正式上市。相比于第12代酷睿性能大涨,内置20条PCle通道(16条PCle 5.0和4条PCle 4.0)、可最多支持128GB DDR5 5600/DDR4 3200双通道内存,搭配Z790系列主板组建高端性能平台,满足未来设计、游戏、专业应用等需求。如…...
uniapp快速回顾,新学websocket连接和BLE连接
Uni APP的学习 官方文档 uni-app官网 (dcloud.net.cn) 任何的博客都不如官方文档 一、快速复习 文件结构 main.js 功能:项目的入口文件,初始化 Vue 实例。 App.vue功能:根组件,包含应用的基本结构和全局样式。 manifest.js…...
激光测距传感器
系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录 前言一、产品原理:二、产品介绍:三、应用特点四、应用案例:1.冶金钢铁板卷材开卷工…...
从数据分析到智能生产:AI在工业中的应用与未来
导语 | 人工智能技术的迅猛发展,正在引领第四次工业革命悄然而至。尽管 AI 技术在工业领域的部署仍有诸多难题亟待解决,但这并不能阻挡历史趋势的车轮滚滚向前,AI 正在为工业领域带来新的变革。今天,我们特邀了上海腾展长融董事 &…...
讲讲android art虚拟机的内存
Android 的 ART(Android Runtime)虚拟机的内存管理是一个复杂但重要的部分。 ART 虚拟机的内存主要包括以下几个关键区域: Java 堆(Java Heap): 这是存储 Java 对象实例的主要区域。堆内存被进一步划分为不…...
构建高效社群生态:探索社群系统的力量与未来
在数字化时代的大潮中,社群系统作为连接人与人、促进信息交流与资源共享的重要平台,正日益成为企业、组织乃至个人不可或缺的一部分。它不仅为成员提供了展示自我、学习成长的舞台,更为社群管理者创造了高效管理、精准运营的工具。今天&#…...
数据结构——排序(3):交换排序(续)
目录 一、快速排序 (1)hoare版本 ①思路 ②过程图示 ③思考 ④代码实现 ⑤代码解释 (2)挖坑法 ①思路 ②过程图示 ③思考 ④代码实现 ⑤代码解释 (3)lomuto前后指针 ①思路 ②过程图示 ③思考 ④代码实现 ⑤代…...
2024最新版本Python安装及开发环境配置(vscodepython)
python安装 去Python官网下载最新版本: 接下来请一步步按照图片操作: 这样子就安装完成了 测试Python安装是否成功 先打开终端 右键Windows徽标,点击终端 然后输入python,如果如下图所示,就说明安装成功࿰…...
机器学习的定义
机器学习 机器学习的定义 机器学习是人工智能的一个分支,它使计算机系统能够从经验中学习并改进,而无需进行明确的编程。机器学习算法分析和解释数据,然后使用该数据来做出预测或决策,随着时间的推移,它们会变得更加准…...
2024-08-05升级问题:Android中ScrollView嵌套listview并解决listview显示问题
问题: 当ScrollView嵌套ListView时,ListView的高度设置为wrap_content时出现ListView的高度不能完全展开,而只显示的第一个Item。 解决方法: 按item的个数乘以高度计算出listview的总高度,并在数据变化时直接设置lis…...
【热度文章】Java设计模式之中介者模 式
ava 中的中介者模式 中介者模式(Mediator Pattern)是一种行为型设计模式,它通过一个中介对象来封装一系列对象之间的交互,使这些对象之间不需要显式地相互引用,从而降低了对象之间的耦合度。 中介者模式的主要角色&…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
push [特殊字符] present
push 🆚 present 前言present和dismiss特点代码演示 push和pop特点代码演示 前言 在 iOS 开发中,push 和 present 是两种不同的视图控制器切换方式,它们有着显著的区别。 present和dismiss 特点 在当前控制器上方新建视图层级需要手动调用…...
