跨域资源共享 (CORS)

一、什么是跨域?

跨域是指浏览器发起的请求,其目标服务器与当前页面的来源(域名、协议、端口)不一致。例如:

  • 同源请求: 页面和接口来源一致,比如:
    • 页面地址:http://example.com
    • 请求接口:http://example.com/api
  • 跨域请求: 页面和接口来源不同,比如:
    • 页面地址:http://localhost:3000
    • 请求接口:http://localhost:8080/api

跨域问题的根源在于 浏览器的同源策略(Same-Origin Policy),这是一种安全机制,防止恶意站点通过 JavaScript 等方式访问用户敏感数据。

同源策略限制:浏览器的同源策略只允许当前网页(前端)的域名、端口、和协议与后端一致。如果前后端运行在不同的端口、协议或域名下(如前端在 http://localhost:3000,后端在 http://localhost:8080),这就是跨域,浏览器会阻止请求。

跨域的目的:

  • 如果跨域配置仅允许特定来源(如前端站点 http://localhost:3000)访问,那就是为了让你的前端能调用后端。
  • 如果配置允许所有来源(*),则是为了对任何来源的请求都开放,可能包括来自其他网站或恶意来源。

二、跨域问题的表现及解决方案

表现: 当浏览器发起跨域请求时,如果目标服务器没有正确配置跨域资源共享(CORS),会报类似以下错误:

Access to XMLHttpRequest at 'http://example.com/api' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

解决方案:
目标服务器通过 CORS 协议,明确告诉浏览器允许跨域请求。CORS 协议依赖以下 HTTP 头部字段:

  • Access-Control-Allow-Origin:允许的请求来源(如 http://localhost:3000*)。
  • Access-Control-Allow-Methods:允许的请求方法(如 GET, POST)。
  • Access-Control-Allow-Headers:允许的请求头(如 Content-Type, Authorization)。
  • Access-Control-Allow-Credentials:是否允许发送 Cookies 和凭据。

三、Spring Boot 中的跨域处理

Spring Boot 提供了多种方式来配置 CORS,根据项目需求灵活选择。

1. 局部跨域配置

使用 @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") // 允许来自 http://localhost:3000 的请求@GetMapping("/api/data")public String getData() {return "Hello, CORS!";}
}

优缺点:

  • 优点: 配置简单,针对单个接口有效。
  • 缺点: 对于多个接口的跨域需求不方便管理。

2. 全局跨域配置

方式 1:CorsRegistry

通过实现 WebMvcConfigurer 接口,配置全局跨域规则,适用于基于 Spring MVC 的项目。

示例代码:

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 WebConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**")  // 匹配所有接口.allowedOrigins("http://localhost:3000") // 允许的请求来源.allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的请求方法.allowedHeaders("*") // 允许的请求头.allowCredentials(true) // 允许携带 Cookies 或凭据.maxAge(3600); // OPTIONS 预检请求的缓存时间}
}
方式 2:CorsWebFilter

对于基于 Spring WebFlux 的响应式项目,需要使用 CorsWebFilter 处理跨域。

示例代码:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;@Configuration
public class CorsConfig {@Beanpublic CorsWebFilter corsWebFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.addAllowedOrigin("*"); // 允许所有来源config.addAllowedHeader("*"); // 允许所有请求头config.addAllowedMethod("*"); // 允许所有方法config.setAllowCredentials(true); // 允许凭据source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}
两种方式的区别
  • CorsRegistry

    • 属于 Spring MVC,用于配置基于 Servlet 的传统 Web 应用。
    • 实现 WebMvcConfigurer 接口,通过 addCorsMappings 方法设置 CORS 规则。
    • 常用于传统的 Spring Boot Web 应用。
  • CorsWebFilter

    • 属于 Spring WebFlux,用于响应式(Reactive)编程模型的项目。
    • 基于过滤器机制实现,配置较灵活。
    • 适合需要处理响应式流的项目(如高并发或非阻塞请求)。

3. Spring Security 跨域处理

Spring Security 默认会拦截跨域请求,必须显式开启跨域支持。

代码示例:

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;@Configuration
@EnableWebSecurity
public class SecurityConfig {@Overrideprotected void configure(HttpSecurity http) throws Exception {http.cors() // 启用跨域支持.and().csrf().disable(); // 禁用 CSRF,避免冲突}
}

注意:
Spring Security 只负责跨域支持的“开关”,具体跨域规则仍需通过 CorsRegistryCorsWebFilter 等方式配置。


4. 通过配置文件处理跨域

Spring Boot 提供了简化的方式,通过 application.propertiesapplication.yml 文件声明跨域规则,无需额外的配置类。

示例配置:

spring.web.cors.allowed-origins=http://localhost:3000
spring.web.cors.allowed-methods=GET,POST,PUT,DELETE
spring.web.cors.allowed-headers=*
spring.web.cors.allow-credentials=true
spring.web.cors.max-age=3600

优点:

  • 配置简单,无需编写代码。
  • 适用于跨域规则稳定的场景。

注意:
即使使用配置文件处理跨域,在 Spring Security 项目中仍需手动开启跨域支持(http.cors())。


四、Spring Cloud Gateway 的跨域处理

在微服务架构中,Spring Cloud Gateway 通常作为 API 网关,代理不同微服务的请求。跨域请求可以在网关层统一处理,避免每个微服务都重复配置跨域。

方式 1:使用 CorsWebFilter

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsWebFilter;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;@Configuration
public class GatewayCorsConfig {@Beanpublic CorsWebFilter corsWebFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration config = new CorsConfiguration();config.addAllowedOrigin("*");config.addAllowedMethod("*");config.addAllowedHeader("*");config.setAllowCredentials(true);source.registerCorsConfiguration("/**", config);return new CorsWebFilter(source);}
}

方式 2:通过 application.yml 配置

spring:cloud:gateway:globalcors:cors-configurations:'[/**]':allowedOrigins: "http://localhost:3000"allowedMethods: "*"allowedHeaders: "*"allowCredentials: true

区别:

  • Spring Cloud Gateway 的 CorsWebFilter 作用于网关层,处理所有通过网关的跨域请求。
  • 普通 WebFlux 项目中的 CorsWebFilter 仅处理单个服务的跨域。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/887112.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Cloud Native 云原生后端的开发注意事项

在云原生后端开发里,数据管理和存储这块得好好弄。数据库选型得综合考虑,像关系型数据有复杂查询需求就选 MySQL、PostgreSQL,海量非结构化数据就可以考虑 MongoDB、Cassandra 这些。设计数据库得遵循规范化原则,像设计电商订单表…

Mac vscode 激活列编辑模式

列编辑模式在批量处理多行文本时,非常有效,但 vscode 默认情况下,又没有激活,因此记录一下启动方法: 激活列编辑模式 然后就可以使用 Alt(Mac 上是 Option 或 Command 键) 鼠标左键 滑动选择了…

c#使用高版本8.0步骤

一、找到项目所在怒路&#xff0c;记事本打开.proj文件。 二、记事本打开此文件&#xff0c;<PropertyGroup>后面加入如下语句&#xff1a; <LangVersion>8.0</LangVersion> 关闭并保存。 根据提示全部重新加载即可。

【蓝桥杯C/C++】深入解析I/O高效性能优化:std::ios::sync_with_stdio(false)

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: 蓝桥杯C/C 文章目录 &#x1f4af;前言&#x1f4af;C 语言与 C 语言的输入输出对比1.1 C 语言的输入输出1.2 C 语言的输入输出 &#x1f4af; std::ios::sync_with_stdio(false) 的作用与意义2.1 什么是 std::ios::sync_with_st…

浏览器的事件循环机制

一、请简述浏览器的事件循环机制&#xff08;Event Loop&#xff09;基本原理 浏览器的事件循环机制是用于协调处理 JavaScript 中的异步任务与同步任务执行顺序的一种机制&#xff0c;它确保了代码能够按照合理的顺序执行&#xff0c;避免阻塞页面渲染等情况。其基本原理如下…

GaussDB 华为高斯数据库

GaussDB 是华为推出的一款企业级分布式数据库&#xff0c;旨在为企业提供高效、可靠、安全的数据库服务。GaussDB 基于华为在数据库领域的多年积累&#xff0c;结合人工智能技术和分布式架构&#xff0c;支持多种场景的数据存储与管理需求&#xff0c;是云计算、大数据、人工智…

【Word】一键批量引用论文上标——将正文字体改为上标格式

【Word】一键批量引用论文上标——将正文字体改为上标格式 写在最前面Word一键批量引用论文上标技巧分享核心思路&#xff1a;Word 替换功能 通配符步骤详解1. 打开 Word 替换功能2. 输入通配符模式3. 设置替换格式为上标4. 批量替换 实际效果展示技巧扩展 &#x1f308;你好呀…

SAP 零售方案 CAR 系统的介绍与研究

前言 当今时代&#xff0c;零售业务是充满活力和活力的业务领域之一。每天&#xff0c;由于销售运营和客户行为&#xff0c;它都会生成大量数据。因此&#xff0c;公司迫切需要管理数据并从中检索见解。它将帮助公司朝着正确的方向发展他们的业务。 这就是为什么公司用来处理…

【深度学习之一】2024最新pytorch+cuda+cudnn下载安装搭建开发环境

兵马未动&#xff0c;粮草先行。作为深度学习的初学者&#xff0c;快速搭建一个属于自己的开发环境就是头等大事&#xff0c;可以让我们节省许多的时间。这一期我们主要讲一讲2024年最新pytorchcudacudnn下载安装搭建开发环境&#xff0c;以及安装过程中可能遇到的一些问题以及…

STM32-- 串口介绍

rs485、rs232、rs422 rs485使用&#xff1a; max3485&#xff1a;3.3v左右驱动 max485&#xff1a;5v左右驱动&#xff0c;不过有时候3.3v驱动也可以使用&#xff0c;具体有什么问题或者通过电路规避问题还没有了解过。 rs485和rs422有相同的地方&#xff0c;485满足422的规…

python oa服务器巡检报告脚本的重构和修改(适应数盾OTP)有空再去改

Two-Step Vertification required&#xff1a; Please enter the mobile app OTPverification code: 01.因为巡检的服务器要双因子认证登录&#xff0c;也就是登录堡垒机时还要输入验证码。这对我的巡检查服务器的工作带来了不便。它的机制是每一次登录&#xff0c;算一次会话…

AI安全:从现实关切到未来展望

近年来&#xff0c;人工智能技术飞速发展&#xff0c;从简单的图像识别到生成对话&#xff0c;从自动驾驶到医疗诊断&#xff0c;AI技术正深刻改变着我们的生活。然而&#xff0c;伴随着这些进步&#xff0c;AI的安全性和可控性问题也日益凸显。这不仅涉及技术层面的挑战&#…

c++ 笔记

基础知识 1. 指针、引用2. 数组3. 缺省参数4. 函数重载5. 内联函数6. 宏7. auto8. const9. 类和对象10. 类的6个默认成员函数11. 初始化列表12. this指针13. C/C的区别14. C 三大特性15. 结构体内存对齐规则16. explicit17. static18. 友元类、友元函数19. 内部类20. 内存管理&…

介绍一下strncmp(c基础)

strncmp是strcmp的进阶版 链接介绍一下strcmp(c基础)-CSDN博客 作用 比较两个字符串的前n位 格式 #include <string.h> strncmp (arr1,arr2,n); 工作原理&#xff1a;strcmp函数按照ACII&#xff08;字符编码顺序&#xff09;比较两个字符串。它从两个字符串的第一…

得物彩虹桥架构演进之路-负载均衡篇

文 / 新一 一、前言 一年一更的彩虹桥系列又来了&#xff0c;在前面两期我们分享了在稳定性和性能2个层面的一些演进&优化思路。近期我们针对彩虹桥 Proxy 负载均衡层面的架构做了一次升级&#xff0c;目前新架构已经部署完成&#xff0c;生产环境正在逐步升级中&#xf…

【ubuntu】数学人的环境搭建

Python 语言环境 python 的 pip 第三方库管理 sudo apt install python3-pippython 的 idle 界面 sudo apt install idle3R 语言环境 sudo apt install r-cran-zoo### RStudio 界面 ubuntu sudo snap install rstudio --classicJulia 语言环境 sudo snap install julia --…

02:spring之AOP

一&#xff1a;AOP 简介 1&#xff1a;AOP的概念 AOP&#xff0c;Aspect Oriented Programming&#xff0c;面向切面编程&#xff0c;是对面向对象编程OOP的升华。OOP是纵向对一个事物的抽象&#xff0c;一个对象包括静态的属性信息&#xff0c;包括动态的方法信息等。而AOP是…

springboot整合hive

springboot整合hive pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.…

初级数据结构——树

目录 前言一、树的基本概念二、二叉树三、树的表示方法四、树的遍历树的代码模版五、经典例题[2236. 判断根结点是否等于子结点之和](https://leetcode.cn/problems/root-equals-sum-of-children/description/)代码题解 六、总结结语 前言 从这一期开始数据结构开始有那么一点…

FreeRTOS信号量(二)

目录 1、计数型信号量简介 1、事件计数 2、资源管理 2、创建计数型信号量 ​编辑1、函数xSemaphoreCreateCounting() 2、函数xSemaphoreCreateCountingStatic() 3 、计数型信号量创建过程分析 4、释放和获取计数信号量 信号量的释放 1 、函数 xSemaphoreGive() 2、函…