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

news2025/5/24 18:33:39

一、同源策略

浏览器的同源策略(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 main

import (
  "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()
}

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

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

相关文章

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

最近在给项目的预览图片页增加共享元素动画的时候&#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 模式通过将对象的共享细节与…

服务器网络配置 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…

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

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

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

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

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…

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

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策略…

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…

Claude 4 系列 Opus 4 与 Sonnet 4正式发布:Claude 4新特性都有哪些?

随着 Claude 4 系列&#xff08;Opus 4 与 Sonnet 4&#xff09;的正式发布&#xff0c;Anthropic 把自家大模型从“会聊天”推进到“能当自主代理”──不仅推理更深、上下文更长&#xff0c;还内置代码执行、多模态理解、工具调用等一揽子全新能力&#xff1b;同时&#xff0…

深度“求索”:DeepSeek+Dify构建个人知识库

目录 前言 环境部署 安装Docker 安装Dify 配置Dify 部署知识库 创建应用 前言 在当今数字化信息爆炸的时代&#xff0c;数据隐私和个性化知识管理成为企业和个人关注的焦点。Dify&#xff0c;作为一款备受瞩目的开源 AI 应用开发平台&#xff0c;为用户提供了完整的私有…