当前位置: 首页 > news >正文

跨域资源共享(CORS)问题与解决方案

跨域资源共享(CORS,Cross-Origin Resource Sharing)是现代web开发中常见且重要的一个概念。它涉及到浏览器的同源策略(Same-Origin Policy),该策略用于防止恶意网站从不同来源窃取数据。然而,在实际开发中,我们经常需要与不同源的资源进行交互,这就引发了跨域问题。本文将详细讨论跨域问题的产生原因、工作流程以及在Spring Boot后端和Axios前端环境中解决跨域问题的方法。

跨域问题的产生原因

同源策略

同源策略是浏览器的一个重要安全机制,用于防止一个网站的脚本与另一个网站的内容进行交互。两个URL被认为是同源的,必须满足以下三个条件:

  1. 协议相同(如http与https不同源)。
  2. 域名相同(如example.com与sub.example.com不同源)。
  3. 端口相同(如http://example.com:80与http://example.com:8080不同源)。

跨域问题

跨域问题产生的原因主要是因为浏览器的同源策略。浏览器限制了从一个源(Origin)加载的文档或脚本与不同源(如不同域、协议或端口)资源的交互。例如,当你的前端应用在http://localhost:3000上运行,而后端API在http://localhost:8080上提供服务时,直接从前端向后端发送请求就会触发跨域问题。

CORS 工作流程

CORS 是一种浏览器技术,它允许服务器明确地表明哪些来源可以访问它的资源。CORS 由一组 HTTP 头部字段组成,这些字段允许服务器描述哪些来源(域、协议和端口)有权限访问服务器上的资源。

简单请求与预检请求

简单请求

简单请求是指那些使用以下方法的请求:

  • GET
  • HEAD
  • POST(带有某些特定类型的Content-Type,如text/plain、multipart/form-data、application/x-www-form-urlencoded)

当浏览器发送一个简单请求时,它会在请求头中包含Origin字段,服务器根据这个字段决定是否允许请求。如果允许,服务器会在响应头中包含Access-Control-Allow-Origin字段。

示例:
前端请求:

axios.get('http://localhost:8080/api/data').then(response => console.log(response.data)).catch(error => console.error(error));

后端响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://localhost:3000
Content-Type: application/json{"data": "some data"
}
预检请求

对于复杂请求(如使用PUT、DELETE方法,或自定义头部字段的请求),浏览器会在实际请求之前发送一个OPTIONS请求,这就是所谓的预检请求。预检请求的目的是探测服务器是否允许实际请求。

预检请求的示例:
前端请求:

axios.post('http://localhost:8080/api/data', {data: 'some data'}, {headers: {'Custom-Header': 'value'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

浏览器发送的预检请求:

OPTIONS /api/data HTTP/1.1
Origin: http://localhost:3000
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Custom-Header

服务器响应:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: Custom-Header

如果预检请求被允许,浏览器会发送实际请求。

Spring Boot中解决CORS问题

在Spring Boot中,我们可以通过多种方式配置CORS策略,允许前端的跨域请求。

使用注解配置CORS

最简单的方式是使用注解@CrossOrigin,可以直接在控制器类或方法上使用该注解。

示例:

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class MyController {@CrossOrigin(origins = "http://localhost:3000")@GetMapping("/api/data")public String getData() {return "some data";}
}

全局配置CORS

如果需要在整个应用程序中统一配置CORS策略,可以通过实现WebMvcConfigurer接口来配置。

示例:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class MyConfig {@Beanpublic WebMvcConfigurer corsConfigurer() {return new WebMvcConfigurer() {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/api/**").allowedOrigins("http://localhost:3000").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*");}};}
}

通过过滤器配置CORS

还可以通过注册一个CORS过滤器来实现跨域配置,这种方式更灵活,可以更好地控制请求的各个方面。

示例:

import org.springframework.stereotype.Component;import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;@Component
public class CorsFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletResponse httpServletResponse = (HttpServletResponse) response;HttpServletRequest httpServletRequest = (HttpServletRequest) request;httpServletResponse.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");httpServletResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");httpServletResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");httpServletResponse.setHeader("Access-Control-Allow-Credentials", "true");if ("OPTIONS".equalsIgnoreCase(httpServletRequest.getMethod())) {httpServletResponse.setStatus(HttpServletResponse.SC_OK);} else {chain.doFilter(request, response);}}
}

Axios配置CORS请求

在前端,我们使用Axios发送HTTP请求。为了处理跨域请求,需要确保Axios正确设置请求头和凭证。

基本使用

基本的GET请求和POST请求已经在前文示例中展示。对于跨域请求,需要特别注意配置withCredentials属性,如果后端需要认证信息(如Cookie)。

示例:

axios.get('http://localhost:8080/api/data', { withCredentials: true }).then(response => console.log(response.data)).catch(error => console.error(error));

自定义请求头

如果需要发送自定义请求头,需要在Axios请求配置中添加相应的头部字段。

示例:

axios.post('http://localhost:8080/api/data', { data: 'some data' }, {headers: {'Custom-Header': 'value'},withCredentials: true
})
.then(response => console.log(response.data))
.catch(error => console.error(error));

处理预检请求

为了确保复杂请求的预检请求能成功,需要在后端正确配置Access-Control-Allow-HeadersAccess-Control-Allow-Methods等头部字段。前端无需额外处理,浏览器会自动发送预检请求。

常见问题与解决方案

缺少CORS头部

如果后端响应中缺少必要的CORS头部,会导致浏览器拦截请求。确保服务器响应中包含Access-Control-Allow-Origin等头部字段。

凭证相关问题

对于需要凭证的请求(如使用Cookie),前端需设置withCredentials: true,后端需设置Access-Control-Allow-Credentials: true

动态CORS配置

有时需要根据请求动态配置CORS策略,可以在过滤器或控制器中编写逻辑,根据请求的来源设置相应的头部字段。

示例:

import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest;@RestController
public class DynamicCorsController {@CrossOrigin@GetMapping("/api/data")public ResponseEntity<String> getData(HttpServletRequest request) {String origin = request.getHeader("Origin");HttpHeaders headers = new HttpHeaders();headers.set("Access-Control-Allow-Origin", origin);headers.set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");headers.set("Access-Control-Allow-Headers", "Content-Type, Authorization");return ResponseEntity.ok().headers(headers).body("some data");}
}

结论

跨域资源共享(CORS)是现代Web开发中不可避免的问题。理解跨域问题的产生原因和工作流程,对于解决跨域问题至关重要。在Spring Boot后端和Axios前端环境中,通过配置注解、全局配置或过滤器,可以

有效解决CORS问题。本文详细探讨了跨域问题的各个方面,希望能为开发者提供有价值的参考。

参考文献

  1. Mozilla Developer Network (MDN) - Cross-Origin Resource Sharing (CORS)
  2. Spring Framework Documentation - Enabling Cross-Origin Requests for a RESTful Web Service
  3. Axios Documentation - Axios

相关文章:

跨域资源共享(CORS)问题与解决方案

跨域资源共享&#xff08;CORS&#xff0c;Cross-Origin Resource Sharing&#xff09;是现代web开发中常见且重要的一个概念。它涉及到浏览器的同源策略&#xff08;Same-Origin Policy&#xff09;&#xff0c;该策略用于防止恶意网站从不同来源窃取数据。然而&#xff0c;在…...

实用软件分享-----一款免费的人工智能替换face的神器

专栏介绍:本专栏主要分享一些实用的软件(Po Jie版); 声明1:软件不保证时效性;只能保证在写本文时,该软件是可用的;不保证后续时间该软件能一直正常运行;不保证没有bug;如果软件不可用了,我知道后会第一时间在题目上注明(已失效)。介意者请勿订阅。 声明2:本专栏的…...

不可思议!这款 Python 库竟然能自动生成GUI界面:MagicGUI

目录 什么是MagicGUI&#xff1f; ​编辑 MagicGUI的工作原理 安装MagicGUI 创建你的第一个GUI ​编辑 其他案例 输入值对话框 大家好&#xff0c;今天我们来聊一聊一个非常有趣且实用的Python库——MagicGUI。这个库可以让你用最少的代码&#xff0c;快速创建图形用户…...

论文发表CN期刊《高考》是什么级别的刊物?

论文发表CN期刊《高考》是什么级别的刊物&#xff1f; 《高考》是由吉林省长春出版社主管并主办的省级教育类期刊&#xff0c;期刊以科教兴国战略为服务宗旨&#xff0c;专门反映和探索国内外教育教学和科研实践的最新成果。该期刊致力于为广大教育工作者提供一个高质量的学术…...

离散数学复习

1.关系的介绍和性质 &#xff08;1&#xff09;序偶和笛卡尔积 两个元素按照一定的顺序组成的二元组就是序偶&#xff0c;使用尖括号进行表示&#xff0c;尖括号里面的元素一般都是有顺序的&#xff1b; 笛卡尔积就是有两个集合&#xff0c;从第一个集合里面选择一个元素&am…...

华为网络设备高频命令

1.system-view • 用法&#xff1a;在用户视图下执行 system-view 命令。 • 作用&#xff1a;进入系统视图&#xff0c;以便进行配置性的操作。 • 场景&#xff1a;当需要对设备进行系统级的配置时。 2.sysname XXX • 用法&#xff1a;执行 [Huawei]sysname XXX 命令。…...

信友队:南风的收集

C. [202406C]楠枫的收集 文件操作 时间限制: 1000ms 空间限制: 262144KB 输入文件名: 202406C.in 输出文件名: 202406C.out Accepted 100 分 题目描述 一年四季&#xff0c;寒暑交替&#xff0c;楠枫总是会收集每一个季节的树叶&#xff0c;并把它们制作成标本收集起来。当…...

找工作小项目:day16-重构核心库、使用智能指针(3)

day16-重构核心库、使用智能指针&#xff08;3&#xff09; 最后将使用这个库的方式进行展示。 1、客户端 在while ((o getopt(argc, argv, optstring)) ! -1)所有的操作都是获取参数的操作&#xff0c;threads 、msgs 和wait 分别指线程数、消息长度以及等待时间。 创建一…...

软考中级|软件设计师-知识点整理

目录 计算机网络概论 计算机系统基础知识 中央处理单元 数据表示 校验码 计算机体系结构 计算机体系结构的发展 存储系统 输入/输出技术 安全性、可靠性与系统性能评测基础知识 加密技术和认证技术 计算机可靠性 程序设计语言基础知识 程序设计语言概述 程序设计…...

HTML5基础

1 HTML基础概念&#xff08;难点&#xff09; WWW&#xff08;World Wide Web&#xff0c;万维网&#xff09;是一种建立在 Internet 上的信息资源网络。 WWW 有 3 个基本组成部分&#xff0c;分别是 URL&#xff1a;Universal Resource Locators&#xff0c;统一资源定位器 HT…...

python,ipython 和 jupyter notebook 之间的关系

python&#xff0c;ipython 和 jupyter notebook 之间的关系 文章目录 python&#xff0c;ipython 和 jupyter notebook 之间的关系1. Python2. IPython3. Jupyter Notebook启动 Jupyter Notebook 关系总结 Python、IPython 和 Jupyter Notebook 是相互关联但具有不同功能的工具…...

聊聊DoIP吧(三)-端口号port

DoIP在UDP和TCP建立连接和发送诊断报文的过程中使用的端口定义如下&#xff1a;...

【将xml文件转yolov5训练数据txt标签文件】连classes.txt都可以生成

将xml文件转yolov5训练数据txt标签文件 前言一、代码解析 二、使用方法总结 前言 找遍全网&#xff0c;我觉得写得最详细的就是这个博文⇨将xml文件转yolov5训练数据txt标签文件 虽然我还是没有跑成功。那个正则表达式我不会改QWQ&#xff0c;但是不妨碍我会训练ai。 最终成功…...

针对k8s集群已经加入集群的服务器进行驱逐

例如k8s 已经有很多服务器&#xff0c;现在由于服务器资源过剩&#xff0c;需要剥离一些服务器出来 查找节点名称&#xff1a; kubectl get nodes设置为不可调度&#xff1a; kubectl cordon k8s-node13恢复可调度 kubectl uncordon k8s-node13在驱逐之前先把需要剥离驱逐的节…...

go 1.22 增强 http.ServerMux 路由能力

之前 server func main() {http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {fmt.Println("Received request:", r.URL.Path)fmt.Fprintf(w, "Hello, client! You requested: %s\n", r.URL.Path)})log.Println("Serv…...

赶紧收藏!2024 年最常见 20道设计模式面试题(二)

上一篇地址&#xff1a;赶紧收藏&#xff01;2024 年最常见 20道设计模式面试题&#xff08;一&#xff09;-CSDN博客 三、解释抽象工厂模式&#xff0c;并给出一个实际应用的例子。 抽象工厂模式是一种创建型设计模式&#xff0c;用于创建一系列相关或依赖对象的接口&#x…...

Java面向对象设计 - Java泛型约束

Java面向对象设计 - Java泛型约束 无限通配符 通配符类型由问号表示&#xff0c;如<&#xff1f;> 。 对于通用类型&#xff0c;通配符类型是对象类型用于原始类型。 我们可以将任何已知类型的泛型分配为通配符类型。 这里是示例代码: // MyBag of String type M…...

什么是内存泄漏?如何避免内存泄漏?

**内存泄漏&#xff08;Memory Leak&#xff09;**是指在程序运行过程中&#xff0c;已经动态分配的堆内存由于某种原因程序未释放或无法释放&#xff0c;造成系统内存的浪费&#xff0c;导致程序运行速度减慢甚至系统崩溃等严重后果。内存泄漏具有隐蔽性、积累性的特征&#x…...

元组(tuple)(Python)

文章目录 一、定义二、常用操作 一、定义 tuple ("张三", "李四", "王二")二、常用操作 分类关键字/函数/方法说明查询元组[索引]根据索引取值&#xff0c;索引不存在会报错len(元组)元组长度&#xff08;元素个数&#xff09;值 in 元组&…...

【C++进阶学习】第二弹——继承(下)——挖掘继承深处的奥秘

继承&#xff08;上&#xff09;&#xff1a;【C进阶学习】第一弹——继承&#xff08;上&#xff09;——探索代码复用的乐趣-CSDN博客 前言&#xff1a; 在前面我们已经讲了继承的基础知识&#xff0c;让大家了解了一下继承是什么&#xff0c;但那些都不是重点&#xff0c;今…...

LangChain-ChatGLM本地搭建|报错合集(win10)

安装过程 1. 创建虚拟环境 conda create -n langchain-chatglm python3.10 conda activate langchain-chatglm2. 部署 langchain-ChatGLM git clone https://github.com/imClumsyPanda/langchain-ChatGLMpip3 install -r requirements.txt pip3 install -U gradio pip3 inst…...

IP地址简介

一、IP地址 Internet Protocol Address&#xff0c;即网络层协议地址&#xff0c;是IP的缩写。 二、IP地址的作用 为什么不直接使用MAC&#xff0c;又加了一个IP地址呢&#xff1f; 事实上底层传输&#xff0c;最终使用的肯定是MAC地址&#xff0c;但是由于在以前&#x…...

谈吐的艺术

被人表扬&#xff0c;该怎么回应 你越是说自己其实没那么好&#xff0c; 对方出于客气&#xff0c; 就越是要证明你其实比你说的好得多。 O可能遇到的问题 每当工作和学习上做出点成绩&#xff0c;有人夸奖我的时候&#xff0c;我都会觉得很尴尬。因为不谦虚会得罪人&#xff…...

Linux 和 分区

文章目录 流程挂载设备文件名 Linux 下各分区的含义家目录 流程 在windows中&#xff0c;一个硬盘要使用只需要分区、格式化之后就可以使用了 在linux中&#xff0c;除了分区和格式化之外&#xff0c;还需要一个叫挂载的操作 挂载 挂载&#xff0c;就相当于windows环境下的写…...

⭐ ▶《强化学习的数学原理》(2024春)_西湖大学赵世钰 Ch3 贝尔曼最优公式 【压缩映射定理】

PPT 截取必要信息。 课程网站做习题。总体 MOOC 过一遍 1、视频 学堂在线 习题 2、过 电子书&#xff0c;补充 【下载&#xff1a;本章 PDF 电子书 GitHub 界面链接】 [又看了一遍视频] 3、总体 MOOC 过一遍 习题 学堂在线 课程页面链接 中国大学MOOC 课程页面链接 B 站 视频链…...

Pikachu上的CSRF以及NSSCTF上的[NISACTF 2022]bingdundun~、 [SWPUCTF 2022 新生赛]xff

目录 一、CSRF CSRF(get) login CSRF(post) CSRF Token 二、CSRF的相关知识点 &#xff08;1&#xff09;什么是CSRF&#xff1f; &#xff08;2&#xff09;工作原理 &#xff08;3&#xff09;CSRF漏洞形成的条件 1、用户要在登录状态&#xff08;即浏览器保存了该…...

大数据分析-二手车用户数据可视化分析

项目背景 在当今的大数据时代&#xff0c;数据可视化扮演着至关重要的角色。随着信息的爆炸式增长&#xff0c;我们面临着前所未有的数据挑战。这些数据可能来自社交媒体、商业交易、科学研究、医疗记录等各个领域&#xff0c;它们庞大而复杂&#xff0c;难以通过传统的数据处…...

AI训练Checkpoint对存储的影响

检查点&#xff08;Checkpoints&#xff09;是机器学习和深度学习训练过程中的一个重要机制&#xff0c;旨在定期保存训练状态&#xff0c;以便在训练过程中遇到失败或中断时能够从中断处恢复训练&#xff0c;而无需从头开始。 随着模型参数量的剧增&#xff0c;Checkpoint文件…...

Python笔记 - 正则表达式

正则表达式&#xff08;Regular Expression&#xff0c;简称regex&#xff09;是一种强大的工具&#xff0c;用于匹配字符串模式。在Python中&#xff0c;正则表达式通过re模块提供。本文将带你深入了解Python中的正则表达式&#xff0c;从基础概念到高级用法。 1. 什么是正则…...

安卓网络通信(多线程、HTTP访问、图片加载、即时通信)

本章介绍App开发常用的以下网络通信技术&#xff0c;主要包括&#xff1a;如何以官方推荐的方式使用多线程技术&#xff0c;如何通过okhttp实现常见的HTTP接口访问操作&#xff0c;如何使用Dlide框架加载网络图片&#xff0c;如何分别运用SocketIO和WebSocket实现及时通信功能等…...

wordpress 后台 java/微信软文案例

最新BAT大厂面试者整理的Android面试题目&#xff01; 近期根据网友分享大厂面试题目&#xff0c;今天我将网友面试的BAT等大厂Android面试题目整理出来&#xff0c;希望能够帮助大家&#xff01; 一、Android基础 Android基础知识点比较多&#xff0c;看图。 建议阅读&…...

wordpress统计分析/东莞网络优化公司

作者 | 张俊鸣素有“大笨象”之称的银行股轻盈起舞&#xff0c;上证指数五天内连攻3000点到3400点之间的五个百点整数关口&#xff0c;“牛市来了”已经成为众多投资者的共识。伴随着汹涌入市的资金潮&#xff0c;日成交破万亿再度成为“新常态”&#xff0c;部分券商的APP一度…...

京东云免费建wordpress/内蒙古seo

一、面向对象编程 ​ 面向过程编程&#xff1a;关注于解决问题的方法、步骤。 ​ 面向对象编程&#xff1a;关注于谁能解决问题(类)&#xff0c;以及解决问题需要的数据(成员变量)&#xff0c;以及解决问题需要的技能(成员函数)。 ​ 抽象&#xff1a;想象出一个能解决问题的…...

温州 网站建设/刷关键词排名软件有用吗

世界那么大&#xff0c;我想去看看。 技术世界波澜壮阔&#xff0c;只做一个前端实在太无趣。 做了那么多年的前端&#xff0c;每天都是做不完的列表页&#xff0c;详情页&#xff0c;弹窗。突然有一天我想玩的新鲜的玩意。 不管怎么说&#xff0c;前端一直都在软件开发中处…...

做美女网站有哪些/推广方法有哪几种

使用npm install报错如下 原因 这是 node-sass、sass-loader 安装的版本和电脑安装的 node.js 版本不兼容导致的错误 解决办法 我的node.js版本是&#xff1a;v12.7.0 在项目目的package.json文件把 node-sass 和 sass-loader 的修改成如下版本&#xff0c;npm i…...

360全景图制作/河南靠谱seo地址

RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。 在这篇文章中&#xff0c;你将会看到 RequestMapping 注解在被用来进行 Spring MVC 控制器方法的映射可以如何发挥其多才多艺的功能的。 Requ…...