1.什么是跨域?

跨域是浏览器为了保障安全而遵循的一种规则,是同源策略的一部分。

  • 同源:要求协议、域名、端口三者完全相同。

  • 跨域:只要协议、域名、端口中有任何一个不同,浏览器就会判定为跨域请求。

跨域(Cross-Origin)是浏览器独有的安全策略,不存在于安卓、iOS、Node.js、Python、Java 等原生客户端或服务器端环境中。因为浏览器是一个开放的、执行不可信代码,也就是各个网站的 js 脚本的环境,同源策略是为了保证用户的信息安全。

所以,如果平时测试接口用的是 postman 发送请求,不需要关心跨域问题,但是如果是前后端联调就必须处理跨域问题。

2.浏览器处理跨域请求的方式

浏览器遵循同源策略,不允许页面获取跨域请求返回的响应结果。

比如:当前网页是 http://127.0.0.1:63342,然后向服务器 http://127.0.0.1:8080 发送 GET 请求获取数据。整个过程分成三步:

  • 浏览器发送请求

  • 服务器接收请求,处理业务,返回响应

  • 浏览器获取服务器返回的响应并根据响应渲染页面

无论是跨域请求还是非跨域请求,浏览器都可以发送给服务器,并且接收服务器返回的响应数据。

  • 如果该请求是非跨域请求,则 js 脚本可以访问响应数据

  • 如果该请求是跨域请求,浏览器会拦截响应数据,不让 js 访问这些数据

其实浏览器可以向不同的域名发送请求,但是浏览器会拦截响应内容,不让 js 访问,无论请求是否成功。

3.跨域处理方案

跨域处理的核心:让浏览器不要拦截跨域请求返回的数据。

服务器的响应中如果有 Access-Control-Allow-Origin: * 这个响应头,就是告诉浏览器:"我是服务器,虽然我跟这个网页不是同源的,但是我允许这个网页跟我通信,我们之间的通信是安全的",浏览器就不会拦截 js 对响应数据的访问。

浏览器发送的请求可以分为简单请求和复杂请求:

  • 如果是简单请求,则浏览器直接发送。

  • 如果是复杂请求,则浏览器先发送一个预检请求,即 OPTIONS 请求,问一句:"我可以发送一个超级复杂的跨域请求吗?",服务器需要返回针对 OPTIONS 的响应。如果服务器允许发送这个复杂请求,浏览器才会真正发送请求。

常见的跨域处理方案有:代理服务器、后端服务器跨域配置。

3.1代理服务器

浏览器将请求发送到跟页面同源的代理服务器,代理服务器再将请求转发到目标服务器。因为服务器间通信不受同源策略限制。比如常见的用 nginx 作为代理服务器。

请求处理过程:

  • 前端发送请求,请求经过 nginx,请求被转发到后端服务器。

  • 服务器返回原始响应,原始响应经过 nginx,nginx 自动添加 Access-Control-Allow-Origin: * 响应头,响应返回给前端,js 可以访问响应数据。

# nginx.conf
server {listen 63342;# 前端页面的域名或ipserver_name 127.0.0.1;# 代理所有以 /api/ 开头的请求到后端服务器location /api/ {# 后端服务器地址proxy_pass http://127.0.0.1:8080/; # 修改请求头,确保后端能收到正确的原始主机信息proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme;# 添加CORS响应头,允许所有来源的请求,生产环境应关闭add_header 'Access-Control-Allow-Origin' '*'; # 允许的请求方法add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE, PATCH';if ($request_method = 'OPTIONS') {# 对于OPTIONS请求,直接返回204状态码,不需要转发到后端return 204;}}
}

3.2 后端跨域配置

3.2.1 配置 CORS

配置全局 CORS 规则,在所有响应头都配置可以跨域访问。

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 WebMvcConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") // 允许所有接口跨域.allowCredentials(true) // 允许浏览器在跨域请求中发送认证信息.allowedOriginPatterns("*") // 允许访问资源的源(协议、域名、端口).allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的方法.allowedHeaders("*") // 允许的请求头.exposedHeaders("*"); // 哪些响应头可以暴露给前端js}
}

3.2.2 提供 CorsFilter

提供一个 CorsFilter 的 Bean 作为过滤器。

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;@Configuration
public class MyCorsFilter {@Beanpublic CorsFilter corsFilter() {CorsConfiguration config = new CorsConfiguration();config.addAllowedOriginPattern("*"); // 放行所有域名,生产环境请对此进行修改config.setAllowCredentials(true); // 是否发送cookieconfig.addAllowedMethod("*");  // 放行的请求方式config.addAllowedHeader("*"); // 放行的请求头config.addExposedHeader("*"); // 暴露头部信息// UrlBasedCorsConfigurationSource: 可以为不同的URL路径设置不同的CORS规则UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();// 所有的URL路径都使用同一个CORS规则corsConfigurationSource.registerCorsConfiguration("/**", config);return new CorsFilter(corsConfigurationSource);}
}

3.2.3 @CrossOrigin 注解

在接口类上或者接口方法上添加 @CrossOrigin 注解,表示整个类、单个接口的响应不会被拦截。

@RestController
@CrossOrigin
public class DemoController {@PutMapping("/put")public Integer put(MultipartFile file) {System.out.println(file.getOriginalFilename());return 200;}@GetMapping("/get")public Integer get() {return 200;}
}

文章转载自:ningqw

原文链接:SpringBoot 常用跨域处理方案 - ningqw - 博客园

体验地址:JNPF快速开发平台

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

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

相关文章

Springboot框架的“上海迪士尼”旅游管理网站设计与开发(代码+数据库+LW)

摘 要 随着旅游行业的不断发展,特别是主题公园的快速增长,如何通过现代信息技术提升旅游服务质量与管理效率成为了行业的重要课题。上海迪士尼作为中国乃至全球知名的主题公园,其旅游管理网站的设计与开发,不只需要满足游客对信…

后台管理系统-16-vue3之动态路由的实现

文章目录 1 动态路由 1.1 stores/index.js(动态添加路由函数) 1.1.1 获取菜单数据 1.1.2 动态导入组件 1.1.3 处理菜单项 1.1.4 添加路由 1.1.5 整体代码 1.2 router/index.js(移除子路由) 1.3 Login.vue(登录页面) 2 多账号bug问题 2.1 问题复现 2.2 解决多账号路由问题(store…

社群团购平台与定制开发开源AI智能名片S2B2C商城小程序的融合创新研究

摘要:本文聚焦于社群团购平台这一在移动互联网背景下兴起的电子商务运营机构,深入剖析其依托移动互联网满足消费者多元购物需求的特点。同时,引入定制开发开源AI智能名片S2B2C商城小程序这一关键元素,探讨二者融合所带来的创新模式…

模型交互中的会话状态管理实践

模型交互中的会话状态管理实践 目录 引言会话状态的手动管理构建多轮对话消息序列追加历史响应实现上下文共享API支持的自动会话状态管理利用 previous_response_id 实现线程式对话模型响应数据保存与计费说明上下文窗口管理与令牌限制令牌计算与窗口溢出风险令牌工具辅助统计…

基于Java+Springboot的船舶运维系统

源码编号:sy23源码名称:基于Springboot的船舶运维系统用户类型:多角色,船员、维修人员、管理员数据库表数量:9 张表主要技术:Java、Vue、ElementUl 、SpringBoot、Maven运行环境:Windows/Mac、J…

零基础也能照做的WordPress网站安全漏洞修复 + 高级优化保姆级教程。

建议先在**暂存环境(Staging)**演练后再动正式站,避免线上故障。下面第一部分就教你“备份暂存还原演练”。 总览导航(按顺序完成) 备份与还原演练(UpdraftPlus 宝塔/阿里/腾讯/七牛)高危加固…

HI3516DV500/HI3519DV500 Docker开发环境配置

目录一、拉取Ubuntu 18.04 docker镜像二、查看已有镜像三、基于镜像创建容器1. 创建容器2. 退出容器3. 查看容器4. 启动容器5. 进入容器6. 更新容器内部软件源四、安装CANN包1. 安装基础依赖环境2. 安装并配置python 3.7.5配置环境变量安装vim添加使环境变量生效检查python版本…

实体店转型破局之道:新零售社区商城小程序开发重构经营生态

在数字化浪潮的席卷下,实体店经营正经历着前所未有的变革与挑战。客户进店率持续走低、同行竞争白热化、经营成本不断攀升、电商平台冲击加剧……这些痛点如同达摩克利斯之剑,悬在传统实体商家的头顶。然而,危机往往与机遇并存,新…

前端-如何将前端页面输出为PDF并打包的压缩包中

需要引入的依赖:import * as utils from ../../utils/utils import html2canvas from "html2canvas"; import JSZip from "jszip"; import JSPDF from "jspdf"; import FileSaver from "file-saver"import { Loading } fro…

LabVIEW 频谱分析应用

LabVIEW 频谱分析程序广泛应用于声学、振动、电力电子等领域,用于噪声频谱分析、设备故障诊断、电能质量评估等。通过模块化 VI 组合,可快速搭建 "信号模拟 - 采集(或缓存)- 频谱分析 - 结果展示" 完整流程,…

北斗导航 | 基于MCMC粒子滤波的接收机自主完好性监测(RAIM)算法(附matlab代码)

详细阐述基于MCMC粒子滤波的接收机自主完好性监测(RAIM)算法的原理、理论和实现方法,并提供完整的MATLAB代码示例。 1. 原理与理论 1.1 接收机自主完好性监测 (RAIM) 简介 RAIM是一种完全由GPS接收机内部实现的算法,用于在不依赖外部系统的情况下,监测GPS信号的完好性(…

【机器学习】4 Gaussian models

本章目录 4 Gaussian models 97 4.1 Introduction 97 4.1.1 Notation 97 4.1.2 Basics 97 4.1.3 MLE for an MVN 99 4.1.4 Maximum entropy derivation of the Gaussian * 101 4.2 Gaussian discriminant analysis 101 4.2.1 Quadratic discriminant analysis (QDA) 102 4.2.2…

Ruoyi-Vue 静态资源权限鉴权:非登录不可访问

一. 背景 移除/profile下静态资源访问权限后,富文本等组件中的图片加载失败!!! 使用ruoyi-vue3.8.9过程中发现上传的在ruoyi.profile下的文件未登录直接使用链接就可以访问下载,感觉这样不太安全,所以想对其进行鉴权限制,修改为只…

关于窗口关闭释放内存,主窗口下的子窗口关闭释放不用等到主窗口关闭>setAttribute(Qt::WA_DeleteOnClose);而且无需手动释放

‌QWidget重写closeEvent后,点击关闭时释放内存会调用析构函数‌,但需注意内存释放的时机和方式。 关闭事件与析构函数的关系 重写closeEvent时,若在事件处理中调用deleteLater()或手动删除对象,析构函数会被触发。但需注意&#…

C# 简单工厂模式(构建简单工厂)

构建简单工厂 现在很容易给出简单工厂类。只检测逗号是否存在,然后返回其中的一个类的实例。 public class NameFactory {public NameFactory(){}public Namer getName(string name){int iname.IndexOf(",");if(i>0)return new LastFirst(name);else{r…

uniappx与uniapp的区别

uniappx与uniapp的定位差异uniappx是DCloud推出的扩展版框架,基于uniapp进行功能增强,主要面向需要更复杂原生交互或跨平台深度定制的场景。uniapp则是标准版,适用于常规的跨平台应用开发,强调开发效率和代码复用。功能扩展性unia…

vue实现拖拉拽效果,类似于禅道首页可拖拽排布展示内容(插件-Grid Layout)

vue实现拖拉拽效果(插件-Grid Layout) 这个是类似与禅道那种首页有多个指标模块,允许用户自己拼装内容的那种感觉。 实现效果 插件资料 vue3版本 如果项目是vue3 的话使用的是 Grid Layout Plus。 官网:https://grid-layout-pl…

在Excel和WPS表格中打印时加上行号和列标

在电脑中查看excel和WPS表格的工作表时,能看到行号(12345.....)和列标(ABCDE...),但是打印出来以后默认是没有行号和列标的,如果要让打印(或者转为PDF)出来以后仍能看到行…

设计模式:原型模式(Prototype Pattern)

文章目录一、原型模式的概念二、原型模式的结构三、原型注册机制四、完整示例代码一、原型模式的概念 原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。通过复制(克隆)已有的实例来创建新的…

Linux系统网络管理

一、网络参数配置1、图形化配置#开启 [rootlocalhost ~]# systemctl start NetworkManager #关闭 [rootlocalhost ~]# systemctl stop NetworkManager #关闭并开机不自启 [rootlocalhost ~]# systemctl disable --now NetworkManager #开启并开机自启 [rootlocalhost ~]# syste…