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

跨域问题及其CORS解决方案:gin框架中配置跨域

一、同源策略

浏览器的同源策略(Same-Origin Policy)要求:只有协议、域名和端口都相同的请求才被视为同源,才允许正常访问。

两个URL在以下三个方面完全相同时称为"同源":

  1. 协议相同(如都是http或https)
  2. 域名相同(如都是example.com)
  3. 端口相同(如都是80端口)

二、同源策略的限制

  • 读取非同源的DOM(iframe、窗口等)
  • 发送AJAX请求到非同源地址
  • 读取非同源的Cookie、LocalStorage等存储数据

例如:

  • https://example.com/page1https://example.com/page2 是同源
  • http://example.comhttps://example.com 不同源(协议不同)
  • https://example.comhttps://sub.example.com 不同源(域名不同)
  • https://example.comhttps://example.com:8080 不同源(端口不同)

三、同源策略的作用

**限制跨源DOM访问:**同源策略规定,不同源的页面无法直接访问彼此的DOM。例如,恶意网站 http://malicious.com 无法通过 JavaScript 读取或修改 http://target.com 的表单数据、页面结构或用户输入内容。这从根本上阻止了XSS攻击者窃取敏感信息(如登录凭据)或篡改页面内容。

**隔离Cookie访问:**浏览器仅允许同源页面访问当前域的Cookie。如果没有这一限制,攻击者可以通过恶意脚本窃取目标网站的会话Cookie,从而冒充用户身份。同源策略确保 http://malicious.com 无法读取 http://target.com 的Cookie,防止会话劫持等攻击。

**独立的脚本执行环境:**不同源的JavaScript运行在隔离的上下文中,无法直接访问其他源的全局变量、函数或对象。例如,即使攻击者在目标网站的评论区注入恶意脚本,该脚本也无法绕过同源策略去窃取或篡改主站的关键数据,从而限制了XSS攻击的危害范围。

**严格限制跨域请求:**默认情况下,浏览器禁止脚本发起跨域HTTP请求(如 fetchXMLHttpRequest),除非目标服务器明确允许(如通过CORS)。这一机制防止攻击者将窃取的数据自动发送到恶意服务器,阻断了XSS攻击的数据外泄途径。

可见同源策略主要是在防止跨站脚本攻击(XSS)

四、同源策略的例外

同源策略虽然是Web安全的重要基石,但为了满足实际开发需求,浏览器也提供了一些合理的例外情况:

静态资源加载<script><img><link><video><audio>等标签允许加载跨域资源,静态资源(如图片、视频)通常不包含敏感数据,同时,虽然可以加载,但JavaScript无法读取这些资源的内容(除非CORS允许)。

CORS(跨源资源共享):通过预检请求和特殊响应头实现受控的跨域访问。现代Web应用需要合法的跨域通信(如前后端分离架构),通过服务器显式声明允许的跨域请求,兼顾安全与功能。

使用JSONP技术进行跨域请求:在CORS出现前的过渡方案,利用脚本标签不受同源限制的特性。

document.domain:允许子域和父域通过设置相同domain进行通信,大型网站常有多个子域(如a.example.comb.example.com),允许同一组织控制的不同子域间安全通信,只能设置为当前域或其父域

五、CORS 解决跨域问题

5.1、对于简单请求

什么是简单请求,可以遵循以下定义:

  • 方法为 GETPOSTHEAD
  • 头部仅包含允许的字段(如 AcceptContent-Typetext/plain/multipart/form-data/application/x-www-form-urlencoded 等)
  • 无自定义头部

服务器在响应中添加 Access-Control-Allow-Origin 头,指定允许的源(或 * 表示允许任意源)

Access-Control-Allow-Origin: https://example.com

浏览器检查该头与当前源匹配后,才会允许响应数据通过。

5.2、对于非简单请求

对于非简单请求(如 PUTDELETE、自定义头部、Content-Type: application/json 等),浏览器会先发送一个 OPTIONS 方法的预检请求,询问服务器是否允许实际请求。

客户端发送的预检请求如下:

OPTIONS /api/data HTTP/1.1
Origin: https://example.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: Content-Type, X-Custom-Header

服务器需响应预检请求,明确声明允许的方法、头部等:

HTTP/1.1 204 No Content
Access-Control-Allow-Origin: https://example.com             // 允许的请求源
Access-Control-Allow-Methods: POST, GET, OPTIONS             // 允许的请求方法
Access-Control-Allow-Headers: Content-Type, X-Custom-Header  // 允许的请求头
Access-Control-Max-Age: 86400  // 缓存预检结果时间(秒)

预检通过的话,客户端就可以发送真实请求:

POST /api/data HTTP/1.1
Origin: https://example.com
Content-Type: application/json
X-Custom-Header: foo

如果预检失败,浏览器会直接拦截真实请求,并在控制台报错。

关键点:

  • 开发者无需手动处理 OPTIONS 请求,浏览器会自动完成。
  • 若预检响应头缺失或错误,真实请求会被拦截。
  • Access-Control-Max-Age 可减少重复预检请求,提升性能。

5.3、对于携带凭据的请求(Credentials)

客户端:请求时必须做额外设置

若请求需要携带 Cookie 或认证信息(如 withCredentials: true),服务器需额外声明:

Access-Control-Allow-Origin: https://example.com  // 不能为 *
Access-Control-Allow-Credentials: true

同时,客户端需显式设置 withCredentials 属性(如 Fetch API 或 Axios)。

Fetch API

fetch('https://api.example.com/data', {method: 'GET',credentials: 'include', // 必须设置为 include 才能发送凭据headers: {'Content-Type': 'application/json',},
});

XMLHttpRequest

const xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.example.com/data', true);
xhr.withCredentials = true; // 必须设置为 true
xhr.send();

Axios

axios.get('https://api.example.com/data', {withCredentials: true, // 必须设置为 true
});

关键点

  • credentials: 'include'(Fetch)或 withCredentials: true(XHR/Axios)必须显式设置,否则浏览器不会发送 Cookies 等凭据。
  • 即使设置了 withCredentials,服务端也必须正确响应 CORS 头,否则请求会被拦截。

服务端:响应 CORS 头(必须严格匹配)

服务端必须在响应中包含以下头部:

Access-Control-Allow-Origin: https://example.com  // 不能是 *,必须明确指定请求来源
Access-Control-Allow-Credentials: true            // 必须为 true
Access-Control-Allow-Methods: GET, POST, OPTIONS  // 允许的方法
Access-Control-Allow-Headers: Content-Type        // 允许的请求头(如自定义头)

关键限制

  • Access-Control-Allow-Origin 不能为 *
  • Access-Control-Allow-Credentials: true 必须存在
  • 如果对于非简单请求,还需要进行预检请求,和 5.1 节 5.2 节一样了

六、Gin框架中配置CORS跨域

Gin 官方推荐使用 github.com/gin-contrib/cors 中间件来配置跨域。

package mainimport ("time""github.com/gin-contrib/cors""github.com/gin-gonic/gin"
)func main() {router := gin.Default()router.Use(cors.New(cors.Config{AllowOrigins:     []string{"https://foo.com"}, // 明确允许访问的域名AllowMethods:     []string{"PUT", "PATCH"},    // 允许的http方法AllowHeaders:     []string{"Origin"},          // 允许客户端在请求中携带的头部字段ExposeHeaders:    []string{"Content-Length"},  // 允许客户端访问的额外响应头(默认只能访问简单头,如 Cache-Control、Content-Language 等)AllowCredentials: true,                        // 允许跨域请求携带凭据AllowOriginFunc: func(origin string) bool {    // 动态验证请求的 Origin 是否合法,优先级高于 AllowOrigins 字段return origin == "https://github.com"},MaxAge: 12 * time.Hour,                        // 预检请求(OPTIONS)的缓存时间}))router.Run()
}

相关文章:

跨域问题及其CORS解决方案:gin框架中配置跨域

一、同源策略 浏览器的同源策略&#xff08;Same-Origin Policy&#xff09;要求&#xff1a;只有协议、域名和端口都相同的请求才被视为同源&#xff0c;才允许正常访问。 两个URL在以下三个方面完全相同时称为"同源"&#xff1a; 协议相同&#xff08;如都是http或…...

记共享元素动画导致的内存泄露

最近在给项目的预览图片页增加共享元素动画的时候&#xff0c;发现了LeakCanary一直报内存泄露。 LeakCanary日志信息 ┬─── │ GC Root: Thread object │ ├─ java.lang.Thread instance │ Leaking: NO (the main thread always runs) │ Thread name: main │ …...

Flyweight(享元)设计模式 软考 享元 和 代理属于结构型设计模式

1.目的&#xff1a;运用共享技术有效地支持大量细粒度的对象 Flyweight&#xff08;享元&#xff09;设计模式 是一种结构型设计模式&#xff0c;它的核心目的是通过共享对象来减少内存消耗&#xff0c;特别是在需要大量相似对象的场景中。Flyweight 模式通过将对象的共享细节与…...

Win/Linux安装flash attention2

1.Win 安装Flash_attn &#xff08;1&#xff09;第一步&#xff1a;下载flash_attn-xxx.whl 文件 在 1&#xff09;地址1&#xff1a;HuggingFace 官网 Flash-attn页面 2&#xff09;地址2&#xff1a;Github 地址 下载对应cuda、torch、python版本的whl文件&#xff1b; …...

【原创】ubuntu22.04下载编译AOSP 15

安装依赖的库&#xff0c;顺便把vim 也安装一下 sudo apt-get install vim sudo apt-get install git gnupg flex bison build-essential zip curl zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils xsltproc unzip font…...

服务器网络配置 netplan一个网口配置两个ip(双ip、辅助ip、别名IP别名)

文章目录 问答 问 # This is the network config written by subiquity network:ethernets:enp125s0f0:dhcp4: noaddresses: [192.168.90.180/24]gateway4: 192.168.90.1nameservers:addresses:- 172.0.0.207- 172.0.0.208enp125s0f1:dhcp4: trueenp125s0f2:dhcp4: trueenp125…...

响应面法(Response Surface Methodology ,RSM)

响应面法是一种结合统计学和数学建模的实验优化技术&#xff0c;通过有限的实验数据&#xff0c;建立输入变量与输出响应之间的数学模型&#xff0c;找到最优操作条件。 1.RSM定义 RSM通过设计实验、拟合数学模型&#xff08;如多项式方程&#xff09;和分析响应曲面&#xff…...

针对面试-java集合篇

1.什么是数组 数组(Array)是一种用连续的内存空间存储相同数据类型数据的线性数据结构。 2.数组下标为什么从0开始 寻址公式是:baseAddressi*dataTyeSize&#xff0c;计算下标的内存地址效率较高 3.查找的时间复杂度 随机(通过下标)查询的时间复杂度是O(1) 查找元素(未知…...

Spring Boot 拦截器:解锁5大实用场景

一、Spring Boot中拦截器是什么 在Spring Boot中&#xff0c;拦截器&#xff08;Interceptor&#xff09;是一种基于AOP&#xff08;面向切面编程&#xff09;思想的组件&#xff0c;用于在请求处理前后插入自定义逻辑&#xff0c;实现权限校验、日志记录、性能监控等非业务功能…...

展锐 Android 15 锁定某个App版本的实现

Android 15 系统锁定Antutu版本的实现方法 在Android系统开发中,有时需要锁定特定应用的版本以确保系统稳定性或测试一致性。本文将介绍如何通过修改Android源码来锁定Antutu跑分软件的版本。 修改概述 这次修改主要涉及以下几个方面: 禁用产品复制文件的检查添加指定版本…...

有两个Python脚本都在虚拟环境下运行,怎么打包成一个系统服务,按照顺序启动?

环境&#xff1a; SEMCP searx.webapp python 问题描述&#xff1a; 有两个python脚本都在虚拟环境下运行&#xff0c;怎么打包成一个系统服务&#xff0c;按照顺序启动&#xff1f; 解决方案&#xff1a; 将这两个 Python 脚本打包成有启动顺序的系统服务&#xff0c;最…...

【Linux cmd】查找进程信息

1、包含 "Test" 关键字的进程 ps -ef | grep Test 显示系统中所有进程的详细信息&#xff0c;包括用户 ID&#xff08;UID&#xff09;、进程 ID&#xff08;PID&#xff09;、父进程 ID&#xff08;PPID&#xff09;、启动时间&#xff08;STIME&#xff09;、终端…...

与网格共舞 - 服务网格的运维与问题排查 (Istio 实例)

与网格共舞 - 服务网格的运维与问题排查 (Istio 实例) 在领略了服务网格(以 Istio 为例)在流量管理、可观测性和安全方面提供的强大能力后,我们自然会思考:如何将这个“神器”请进我们的生产环境,并让它稳定、可靠地运行?这需要我们关注运维层面的实践。 部署与升级:网…...

Python 脚本执行命令的深度探索:方法、示例与最佳实践

在现代软件开发过程中&#xff0c;Python 脚本常常需要与其他工具和命令进行交互&#xff0c;以实现自动化任务、跨工具数据处理等功能。Python 提供了多种方式来执行外部命令&#xff0c;并获取其输出&#xff0c;重定向到文件&#xff0c;而不是直接在终端中显示。这种能力使…...

PotPlayer 4K 本地万能影音播放器

今日分享一款来自吾爱论坛大佬分享的啥都能播的的本地播放器&#xff0c;不管是不管是普通视频、4K超清、蓝光3D&#xff0c;还是冷门格式&#xff0c;它基本都能搞定。而且运行流畅不卡顿&#xff0c;电脑配置低也能靠硬件加速&#xff0c;让你根本停不下来。 自带解码器&…...

2025年电工杯A题第一版本Q1-Q4详细思路求解+代码运行

A题 光伏电站发电功率日前预测问题 问题背景 光伏发电是通过半导体材料的光电效应&#xff0c;将太阳能直接转化为电能的技术。光伏电站是由众多光伏发电单元组成的规模化发电设施。 光伏电站的发电功率主要由光伏板表面接收到的太阳辐射总量决定&#xff0c;不同季节太阳光…...

基于阿里云DashScope API构建智能对话指南

背景 公司想对接AI智能体&#xff0c;用于客服系统&#xff0c;经过调研和实施&#xff0c;觉得DashScope 符合需求。 阿里云推出的DashScope灵积模型服务为开发者提供了便捷高效的大模型接入方案。本文将详细介绍如何基于DashScope API构建一个功能完善的智能对话系统&#x…...

HOW - 基于组件库组件改造成自定义组件基本规范

文章目录 Select 选择器改造1. 明确组件目标2. 定义组件 API3. 合理使用默认值4. 支持类型安全的 options 传递5. 支持 ForwardRef&#xff08;可选&#xff09;6. 封装样式&#xff08;可选&#xff09;7. 使用示例 ...props 位置推荐顺序&#xff1a;最后原因&#xff1a;简要…...

九州未来十三载:开源赋能 智启未来

2012年&#xff0c;九州未来以“开源赋能云边变革”为使命&#xff0c;开启中国开放云边基础架构服务的探索之路。十三载坚守深耕&#xff0c;我们始终以开源为翼&#xff0c;以算力为基&#xff0c;在科技浪潮中砥砺前行&#xff0c;见证并推动着AI时代的算力变革。 坚守初心丨…...

2025年AI搜索引擎发展洞察:技术革新与市场变革

引言&#xff1a;AI搜索的崛起与市场格局重塑 2024-2025年&#xff0c;AI搜索市场迎来了前所未有的变革期。随着DeepSeek-R1等先进大语言模型的推出&#xff0c;传统搜索引擎、AI原生搜索平台以及各类内容平台纷纷加速智能化转型&#xff0c;推动搜索技术从基础信息检索向深度…...

dify调用Streamable HTTP MCP应用

一、概述 上一篇文章&#xff0c;介绍了使用python开发Streamable HTTP MCP应用&#xff0c;链接&#xff1a;https://www.cnblogs.com/xiao987334176/p/18872195 接下来介绍dify如何调用MCP 二、插件 安装插件 需要安装2个插件&#xff0c;分别是&#xff1a;Agent 策略(支持 …...

HCIP实验五

一、实验拓扑图&#xff1a; 二、实验需求分析&#xff1a; 1. PreVal策略&#xff1a;要求确保R4通过R2到达192.168.10.0/24 &#xff0c;需在R4上针对去往该网段路由配置PreVal策略&#xff0c;为经R2的路径赋予更高优先值&#xff0c;影响本地路由表选路。 2. AS Path策略…...

java将图片转Base64字符串存储mysql数据库

1、mysql数据库的表里新增一个字段image_data&#xff0c;使用TEXT或LONGTEXT类型&#xff1a; CREATE TABLE IMAGES( id INT AUTO_INCREMENT PRIMARY KEY, image_name VARCHAR(255), image_data LONGTEXT, upload_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); 2、Java核心…...

题目 3330: 蓝桥杯2025年第十六届省赛真题-01 串

题目 3330: 蓝桥杯2025年第十六届省赛真题-01 串 时间限制: 2s 内存限制: 192MB 提交: 310 解决: 24 题目描述 给定一个由 0, 1, 2, 3 的二进制表示拼接而成的长度无限的 01 串。 其前若干位形如 011011100101110111 。 请求出这个串的前 x 位里有多少个 1 。 输入格…...

初识 Flask 框架

目录 1. Flask 框架概述 1.1 安装 Flask 1.2 创建你的第一个 Flask 应用 1.3 运行 Flask 应用 2. Flask 路由与视图函数 2.1 动态路由 2.2 支持多种 HTTP 请求方法 2.3 使用 Jinja2 模版渲染 HTML 2.5 模版继承与块 3. Flask 表单处理与用户输入 3.1 安装 Flask-WTF …...

MYSQL故障排查和环境优化

一、MySQL故障排查 1. 单实例常见故障 &#xff08;1&#xff09;连接失败类问题 ERROR 2002 (HY000): Cant connect to MySQL server 原因&#xff1a;MySQL未启动或端口被防火墙拦截。 解决&#xff1a;启动MySQL服务&#xff08;systemctl start mysqld&#xff09;或开放…...

vivado fpga程序固化

一般下载到fpga上的程序在掉电之后就会丢失&#xff0c;如果想要掉电之后程序不丢失&#xff0c;就需要将比特流文件固化到板载的flash上。 以下以我的7a100t开发板为例&#xff0c;介绍程序固化的流程 点击OK就可以下载了。 一个奇怪的问题 有一次我的一个工程固化之后&…...

OpenCV CUDA模块图像特征检测与描述------图像中快速检测特征点类cv::cuda::FastFeatureDetector

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 cv::cuda::FastFeatureDetector 是 OpenCV 的 CUDA 加速模块中的一部分&#xff0c;用于在图像中快速检测特征点。FAST&#xff08;Features fro…...

SpringMVC(结合源码浅析工作流程)

SpringMVC 概念 Spring MVC 是基于前端控制器&#xff08;Front Controller&#xff09;设计模式的 Web 框架&#xff0c;在 Web 应用中指一个统一的入口&#xff0c;用来接收所有客户端请求&#xff0c;并统一进行分发、处理。在 SpringMVC 中&#xff0c;前端控制器就是 Di…...

学习STC51单片机13(芯片为STC89C52RC)

我去&#xff0c;兄弟们我们今天来学习一个牛逼 的硬件&#xff0c;它叫超声波测距模块HC—SR04 硬件&#xff1a;HC—SR04 哎&#xff0c;想当初最想要玩的就是这个模块&#xff0c;科技感十足&#xff0c;那现在就让我们玩玩吧 超声波测距传感器 原理就是说需要给Trig 10u…...