跨域资源共享 (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,一经查实,立即删除!

相关文章

资源控制器--laravel进阶篇

laravel的控制器当中有个资源控制器,这个比较好用。 创建资源控制器 php artisan make:controller PhotoController --resource 创建个路由来使用该资源控制器 use App\Http\Controllers\PhotoController; Route::resource(photos, PhotoController::class); 隐式模型绑定不…

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…

OpenCV 计算图像清晰度

文章目录 一、简介二、实现代码三、实现效果一、简介 我们往往怎么定义一个图像的清晰度呢,通常来讲一个图像的清晰度越高,其图像细节越丰富,也就是说我们通常可以通过图像的高频信息(如边缘或噪声)来衡量。OK,既然如此,这里可以使用 拉普拉斯算子(cv::Laplacian)先对…

浏览器的事件循环机制

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

Oracle-表空间/用户的创建与使用

-- 对象 -- 需要create的都是对象 已学的对象&#xff1a;表 table -- 普通用户 只能查询user开头的数据字典 select tablespace_name from user_tablespaces; -- dba用户才能够查询 select tablespace_name from dba_tablespaces; -- 创建表空间&#xff08;需要管理员…

GaussDB 华为高斯数据库

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

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

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

C#里怎么样访问文件时间

C#里怎么样访问文件时间 文件时间也是一个关键信息, 因为很多数据处理需要时间来判断数据的有效性,比如股票中的股价, 它是的权重,是随着时间递减的。 一般来说,超过5年以上的数据,都是可以删除掉了。 或者说超过三年的数据,就需要压缩保存了,这样可以省掉很多磁盘空…

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

前言 当今时代&#xff0c;零售业务是充满活力和活力的业务领域之一。每天&#xff0c;由于销售运营和客户行为&#xff0c;它都会生成大量数据。因此&#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. 内存管理&…

MyBatis的resultType和resultMap区别

resultType和resultMap是在使用 MyBatis 框架时&#xff0c;映射查询结果到对象时使用的两个不同的配置元素。它们的主要区别在于它们如何映射 SQL 查询的结果集到 Java 对象。 1. resultType resultType是一个简单的类型别名或者是一个完全限定的类名。 它用于将查询结果直接…

PyTorch图像预处理:计算均值和方差以实现标准化

在深度学习中&#xff0c;图像数据的预处理是一个关键步骤&#xff0c;它直接影响模型的训练效果和收敛速度。PyTorch提供的transforms.Normalize()函数允许我们对图像数据进行标准化处理&#xff0c;即减去均值并除以方差。这一步骤对于提高模型性能至关重要。 为什么需要标准…