解决跨域问题方案
跨域问题在前后端分离架构下尤为常见,是每个 Web 开发者都会遇到的核心问题。本文将通过原理解析、场景剖析、解决方案详解以及最佳实践等多个维度,帮助开发者全面理解并有效应对跨域问题。
目录
- **一、跨域的本质**
- **1. 同源策略**
- **2. 同源策略的限制范围**
- **3. 为什么需要同源策略**
- **二、跨域问题的常见场景**
- **1. 前后端分离**
- **2. 第三方服务调用**
- **3. 静态资源加载**
- **4. 跨协议请求**
- **三、跨域的解决方案详解**
- **1. CORS(跨域资源共享)**
- **CORS 在 Spring Boot 中的配置**
- **2. 代理服务器转发**
- **3. JSONP(仅支持 GET 请求)**
- **4. iframe + postMessage**
- **5. 后端设置 JSONP API**
- **四、最佳实践**
- **五、总结**
一、跨域的本质
1. 同源策略
跨域问题的根本源于浏览器的同源策略(Same-Origin Policy)。同源策略是浏览器的一种安全机制,用于限制不同源的文档或脚本如何彼此交互,以保护用户的数据安全。
-
同源的定义:协议、域名、端口号必须一致。
属性 示例 1 示例 2 是否同源 协议 http://example.comhttps://example.com否 域名 http://example.comhttp://api.example.com否 端口号 http://example.com:80http://example.com:8080否
2. 同源策略的限制范围
同源策略主要限制以下行为:
- Cookie、LocalStorage 和 SessionStorage 的读取
- DOM 和 JavaScript 对象的访问
- AJAX 请求(尤其是跨域数据的访问)
3. 为什么需要同源策略
同源策略主要是为了防止以下安全风险:
- 跨站脚本攻击(XSS):恶意页面通过脚本窃取用户数据。
- 跨站请求伪造(CSRF):利用用户身份对目标网站执行未授权操作。
- 数据劫持:防止不受信任的域窃取敏感信息。
二、跨域问题的常见场景
1. 前后端分离
现代 Web 应用通常采用前后端分离架构,前端通过 AJAX 请求与后端进行交互。当前端和后端运行在不同的域时,会触发跨域问题。例如:
- 前端:
http://localhost:3000 - 后端:
http://localhost:8080
2. 第三方服务调用
前端需要请求第三方 API,例如调用 https://api.example.com 提供的开放服务,这种场景也会引发跨域问题。
3. 静态资源加载
页面运行在 http://example.com,而静态资源托管在 CDN(如 https://cdn.example.com)上。
4. 跨协议请求
例如从 HTTP 页面调用 HTTPS 服务。
三、跨域的解决方案详解
1. CORS(跨域资源共享)
CORS 是 W3C 提出的标准解决方案,允许服务端通过设置特定的响应头,告知浏览器允许跨域访问。
- CORS 的关键响应头:
Access-Control-Allow-Origin:允许的源(如http://example.com,或*代表允许所有源)。Access-Control-Allow-Methods:允许的 HTTP 方法(如GET, POST)。Access-Control-Allow-Headers:允许的自定义请求头(如Authorization)。Access-Control-Allow-Credentials:是否允许携带凭证(如 Cookie)。Access-Control-Max-Age:预检请求的缓存时间。
CORS 在 Spring Boot 中的配置
Spring Boot 提供了多种方式支持 CORS:
-
全局配置
使用WebMvcConfigurer添加全局的 CORS 配置。@Configuration public class WebConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**").allowedOrigins("http://example.com").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").allowCredentials(true).maxAge(3600);} } -
局部配置
在控制器类或方法上使用@CrossOrigin注解。@RestController @RequestMapping("/api") public class MyController {@CrossOrigin(origins = "http://example.com")@GetMapping("/data")public ResponseEntity<String> getData() {return ResponseEntity.ok("Hello, World!");} } -
通过过滤器统一配置
使用OncePerRequestFilter创建全局 CORS 过滤器。@Component public class CORSFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)throws ServletException, IOException {response.setHeader("Access-Control-Allow-Origin", "*");response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");response.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");response.setHeader("Access-Control-Allow-Credentials", "true");filterChain.doFilter(request, response);} }
2. 代理服务器转发
通过代理服务器将跨域请求转发为同源请求,避免跨域问题。
-
开发环境中的前端代理
- React 配置代理:
{"proxy": "http://localhost:8080" } - Vue 配置代理:
module.exports = {devServer: {proxy: {'/api': {target: 'http://localhost:8080',changeOrigin: true,pathRewrite: { '^/api': '' }}}} };
- React 配置代理:
-
Nginx 反向代理
server {listen 80;server_name example.com;location /api/ {proxy_pass http://backend-service:8080;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;} }
3. JSONP(仅支持 GET 请求)
通过 <script> 标签加载远程数据,并利用回调函数实现跨域通信。
-
前端调用示例:
<script>function handleResponse(data) {console.log(data);} </script> <script src="http://example.com/api?callback=handleResponse"></script> -
后端返回数据:
handleResponse({"message": "success"});
4. iframe + postMessage
通过嵌入跨域的 iframe,并使用 postMessage 方法实现通信。
- 父页面代码:
const iframe = document.getElementById('myIframe'); iframe.contentWindow.postMessage('hello', 'http://example.com');window.addEventListener('message', (event) => {if (event.origin === 'http://example.com') {console.log(event.data);} });
5. 后端设置 JSONP API
在后端返回一个 JavaScript 函数的调用来传递数据,这种方法兼容性较好但仅适用于简单场景。
四、最佳实践
-
安全性:
- 指定可信任的跨域源,不建议使用通配符(
*)。 - 对敏感数据接口加强认证和授权控制。
- 指定可信任的跨域源,不建议使用通配符(
-
性能优化:
- 使用
Access-Control-Max-Age缓存预检请求结果。 - 减少跨域请求次数,合并或延迟请求。
- 使用
-
复杂场景下的组合解决方案:
- 开发阶段使用前端代理,生产环境使用 Nginx 反向代理。
- 配合 CORS 配置和全局过滤器处理复杂跨域请求。
五、总结
跨域问题是浏览器同源策略带来的限制,其根本目的是保护用户数据安全。通过 CORS 配置、全局过滤器、代理服务器等方法,可以灵活解决不同场景下的跨域问题。在实际开发中,应结合项目需求,选择最合适的解决方案,同时注重安全性和性能优化,从而构建更高效、更安全的 Web 应用。
相关文章:
解决跨域问题方案
跨域问题在前后端分离架构下尤为常见,是每个 Web 开发者都会遇到的核心问题。本文将通过原理解析、场景剖析、解决方案详解以及最佳实践等多个维度,帮助开发者全面理解并有效应对跨域问题。 目录 **一、跨域的本质****1. 同源策略****2. 同源策略的限制范…...
云计算介绍_3(计算虚拟化——cpu虚拟化、内存虚拟化、io虚拟化、常见集群策略、华为FC)
计算虚拟化 1.计算虚拟化介绍1.1 计算虚拟化 分类(cpu虚拟化、内存虚拟化、IO虚拟化)1.2 cpu虚拟化1.3 内存虚拟化1.4 IO虚拟化1.5 常见的集群的策略1.6 华为FC 1.计算虚拟化介绍 1.1 计算虚拟化 分类(cpu虚拟化、内存虚拟化、IO虚拟化&#…...
软件工程复习记录
基本概念 软件工程三要素:方法、工具、过程 软件开发方法:软件开发所遵循的办法和步骤,以保证所得到的运行系统和支持的文档满足质量要求。 软件开发过程管理 软件生命周期:可行性研究、需求分析、概要设计、详细设计、编码、测…...
俩Nim游戏
1.给定n堆石子,每堆石子有xi快,两位玩家轮流操作,每次操作可以从任意一堆石子中拿走任意数量的石子(可以拿完,但不能不拿),最后无法进行操作的人视为失败。 问如果两人都采用最优策略ÿ…...
基于超级电容和电池的新能源汽车能量管理系统simulink建模与仿真
目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 超级电容特性 4.2 电池特性 5.完整工程文件 1.课题概述 基于超级电容和电池的新能源汽车能量管理系统simulink建模与仿真。分析不同车速对应的电池,超级电容充放电变化情况。 2.系统仿…...
数据结构——图(遍历,最小生成树,最短路径)
目录 一.图的基本概念 二.图的存储结构 1.邻接矩阵 2.邻接表 三.图的遍历 1.图的广度优先遍历 2.图的深度优先遍历 四.最小生成树 1.Kruskal算法 2.Prim算法 五.最短路径 1.单源最短路径--Dijkstra算法 2.单源最短路径--Bellman-Ford算法 3.多源最短路径--Floyd-…...
002-NoSQL介绍
目录 一、NoSQL 简介 二、NoSQL 特性 三、NoSQL 的工作原理 四、NoSQL 有哪些类型 五、NoSQL数据库与关系型数据库的区别 六、常见的非关系型数据库NOSQL分类 一、NoSQL 简介 NoSQL,全称为Not Only SQL,指的是非关系型的数据库。NoSQL有时也称作Not Only SQL的缩写,是…...
qt-everywher交叉编译e-src-5.15.2
简化配置的方式: 你完全可以通过直接配置 安装目录、编译链 和 目标架构 来完成交叉编译,而不需要修改 mkspecs 配置。以下是如何通过简化配置来进行交叉编译 Qt 的步骤。 准备交叉编译工具链 首先,确保你已经安装了交叉编译工具链ÿ…...
4.STM32通信接口之SPI通信(含源码)---硬件SPI与W25Q64存储模块通信实战《精讲》
开胃简介 根据上一节对STM32的SPI介绍!本节将进行硬件SPI的实现,片选用软件实现!跟着Whappy走起!W25Q64的驱动层,我们不需要更改,仅仅需要更改一下SPI的协议,即:由软件实现改成硬件…...
生信技能63 - 构建gnomAD变异位点的SQLite查询数据库
将数据量巨大的gnomAD数据库,通过SQLite数据库寻找gnomAD中存在的各种变异注释信息(如等位基因计数,深度,次要等位基因频率等),查询300.000个变量的查询需要大约40秒,通过染色体编号+位置+REF+ALT即可进行快速查询。 1. gnomAD变异注释VCF文件字段 gnomAD VCF各版本包…...
0x0118消息 WM_SYSTIMER
0x0118消息就是WM_SYSTIMER 编辑框出现输入光标时,产生的消息. 0x0118 would be the undocumented WM_SYSTIMER, which appears to be used for caret blinks. 0x0118是一个undocument 消息, 微软没有记录。 但在一些库的源码中可以看到,比如ATL的库文…...
【机器学习】机器学习的基本分类-无监督学习(Unsupervised Learning)
无监督学习(Unsupervised Learning) 无监督学习是一种机器学习方法,主要用于没有标签的数据集。其目标是从数据中挖掘出潜在的结构和模式。常见的无监督学习任务包括 聚类、降维、密度估计 和 异常检测。 1. 无监督学习的核心目标 1.1 聚类…...
[代码随想录09]字符串2的总结
前言 处理字符串主要是有思路,同时总结方法。 题目链接 151. 反转字符串中的单词 - 力扣(LeetCode) 55. 右旋字符串(第八期模拟笔试) 一、翻转字符串里的单词 这个题目的主要思路,代码采用从后往前遍历字…...
java注解(一):什么是注解?什么是元注解?如何自定义注解?注解的原理是什么?
目录 1、什么是注解? 2、什么是元注解 1、Target() 2、Retention() 3、Documented 4、Inherited 3、如何自定义注解以解使用 4、注解的原理 本篇文章主要是介绍注解的概念、原理,以及通过代码演示4种元注解、如何自定义注解。通过反编译的形式进…...
AD20 原理图库更新到原理图
一 点击工具,从库更新。快捷键TL 二 点击完成 三 执行变更,最后点击关闭...
.NET用C#导入Excel数据到数据库
将Excel文件中的数据导入到数据库中不仅能够提升数据处理的效率和准确性,还能极大地促进数据分析和决策制定的过程。尤其在企业级应用中,Excel作为数据输入和初步整理的工具非常普遍,但其功能对于复杂查询、大规模数据管理和跨部门的数据共享…...
小身躯大能量-供热系统通过EtherCAT转Profinet网关进行升级
在现代工业自动化领域,通信技术的进步对于提高系统效率、稳定性和可靠性起着至关重要的作用。EtherCAT(Ethernet for Control Automation Technology)作为一种实时以太网解决方案,因其高性能及成本效益高等特点,在众多…...
Android11.0系统关闭App所有通知
通过广播接收方式,根据包名关闭App所有通知。 packages/apps/Settings$ git diff diff --git a/AndroidManifest.xml b/AndroidManifest.xml index d4c54c6ed8..1ce7d4136f 100644 --- a/AndroidManifest.xmlb/AndroidManifest.xml-106,6 106,7 <uses-permissio…...
# issue 8 TCP内部原理和UDP编程
TCP 通信三大步骤: 1 三次握手建立连接; 2 开始通信,进行数据交换; 3 四次挥手断开连接; 一、TCP内部原理--三次握手 【第一次握手】套接字A∶"你好,套接字B。我这儿有数据要传给你,建立连接吧。" 【第二次…...
力扣100题--移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例 1: 输入: nums [0,1,0,3,12] 输出: [1,3,12,0,0]示例 2: 输入: nums [0] 输出: […...
简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
PHP和Node.js哪个更爽?
先说结论,rust完胜。 php:laravel,swoole,webman,最开始在苏宁的时候写了几年php,当时觉得php真的是世界上最好的语言,因为当初活在舒适圈里,不愿意跳出来,就好比当初活在…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一)
宇树机器人多姿态起立控制强化学习框架论文解析 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(一) 论文解读:交大&港大&上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
