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

用go实现cors中间件

目录

一、概述

二、简单请求和预检请求

简单请求

预检请求

三、使用go的gin框架实现cors配置

1、安装

2、函数


一、概述

        CORS(Cross-Origin Resource Sharing)是一种浏览器安全机制,用于控制在Web应用程序中不同源(Origin)之间的资源共享。一个源是由协议(例如http或https)、主机(例如 www.example.com)、以及端口(例如80或443)组成的组合。CORS允许服务器定义哪些源可以访问其资源,以及哪些HTTP方法和头部可以在跨源请求中使用。

要点:

  1. 同源策略(Same-Origin Policy):Web浏览器实施了同源策略,它限制了一个页面中加载的资源只能来自相同的源,以防止而已站点获取用户的敏感信息。这意味着默认情况下,跨域请求是被浏览器禁止的。
  2. 跨源HTTP请求:当一个Web页面需要从不同源的服务器获取数据时,例如通过AJAX请求或嵌入其他站点的资源(如字体、图片或脚本),就会设计到跨源HTTP请求。
  3. CORS解决跨域问题: CORS是一种机制,允许服务器在响应中添加HTTP标头来指示浏览器允许跨域请求。这些标头包括”Access-Control-Allow-Origin“、”Access-Control-Allow-Methods“、”Access-Control-Allow-Headers“等
  4. 简单请求和预检请求:浏览器将跨域HTTP请求分为两种类型:简单请求(Simple Request)和预检请求(Preflight Request)。简单请求就是常见的GET、POST请求,而预检请求时一种用于检查服务器是否支持某些请求的OPTION请求。
  5. 服务器配置:CORS的服务器配置通常在服务器端完成。服务器需要响应OPTIONS请求并在响应头中包含CORS标头来指定允许的来源、HTTP方法和头部。服务器还可以选择性地要求携带凭据(credentials)
  6. 浏览器行为:浏览器在发送跨域请求时会自动附加Origin头,然后根据服务器的响应判断是否允许访问资源。如果CORS设置不正确,浏览器会阻止页面访问响应的数据。

二、简单请求和预检请求

简单请求

1、判定条件

需要同时满足以下条件,浏览器会认为它是一个简单请求

  • 请求方法属于其中一种:GET、POST、HEAD
  • 请求包仅包含安全的字段,常见字段:Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save-Data、Viewport-Width、Width
  • 请求头如果包含Content-Type,仅限如下值:text/plain、multipart/form-data、application/x-www-form-urlencoded

2、简单请求交互

①当浏览器判某个跨域请求时简单请求时,会在请求头中自动添加Origin字段

GET /cors HTTP/1.1
Host: example.com
Connection: keep-alive
...
Referer: http://local.com/index.html
Origin: http://local.com //Origin字段会告诉服务器,是哪个源地址在跨域请求

②服务器响应头中应包含Access-Control-Allow-Origin ,当服务器收到请求后,如果允许改请求跨域访问,需要在响应头中添加Access-Control-Allow-Origin字段

HTTP/1.1 200 OK
Date: Tue, 21 Jun 2023 08:03:35 GMT
...
Access-Control-Allow-Origin: http://local.com
...消息体中的数据

当浏览器看到服务器允许自己访问后,于是,它就把响应顺利的交给js

预检请求

1、对于预检请求,请求步骤如下:

  • 浏览器发送预检请求,询问服务器是否允许
  • 服务器响应是否允许
  • 浏览器发送真实请求
  • 服务器完成真实的响应

2、步骤请求演示

要发送的请求包:

POST /cors HTTP/1.1

Host: example.com

Connection: keep-alive ...

Referer: http://local.com/index.html

Origin: http://local.com

{"name": "admin", "age": 20}

①浏览器发送预检请求

OPTIONS /cors HTTP/1.1
Host: example.com
...
Origin: http://local.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: a, b, content-type

ps:这并非想要发出的真实请求,请求中不包含响应头和也没有消息体。

预检请求特征:

请求方法为OPTIONS 没有请求体

  • 请求头中包含 Origin:请求的源,和简单请求的含义一致
  • Access-Control-Request-Method:后续的真实请求将使用的请求方法
  • Access-Control-Request-Headers:后续的真实请求会改动的请求头

②服务器允许

服务器收到预检请求后,可以检查预检请求中包含的信息,如果允许这样的请求,需要响应下面的消息格式

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: http://local.com
Access-Control-Allow-Methods: POST
Access-Control-Allow-Headers: a, b, content-type
Access-Control-Max-Age: 86400
...

对于预检请求,不需要响应任何的消息体,只需要在响应头中添加: 

Access-Control-Allow-Origin:和简单请求一样,表示允许的源 Access-Control-Allow-Methods:表示允许的后续真实的请求方法 Access-Control-Allow-Headers:表示允许改动的请求头 Access-Control-Max-Age:告诉浏览器,多少秒内,对于同样的请求源、方法、头,都不需要再发送预检请求了

③浏览器发送真实请求

预检被服务器允许后,浏览器就会发送真实请求了,上面的代码会发送下面的请求数据

POST /cors HTTP/1.1Host: example.comConnection: keep-alive ...Referer: http://local.com/index.htmlOrigin: http://local.com{"name": "admin", "age": 20}

④服务器响应真实请求

HTTP/1.1 200 OK
Date: Tue, 21 Jun 2023 08:03:35 GMT
...
Access-Control-Allow-Origin: http://local.com
...添加用户成功

三、使用go的gin框架实现cors配置

使用go的gin框架的话,说白了就是添加一个中间件,Gin官方提供CORS中间件,可以很方便的使用 cors解决跨域问题。

1、安装

使用命令安装该中间件

go get github.com/gin-contrib/cors

2、函数

cors中间件提供三个函数,代表三种使用方式,分别是NEWDefaultConfigDefault

  • NEW方式

可以接收 CORS 中间件的配置项,可通过自定义配置项,满足任意需要跨域的场景。

示例:
router.Use(cors.New(cors.Config{AllowOrigins:     []string{"https://foo.com"},AllowMethods:     []string{"PUT", "PATCH"},AllowHeaders:     []string{"Origin"},ExposeHeaders:    []string{"Content-Length"},AllowCredentials: true,AllowOriginFunc: func(origin string) bool {return origin == "https://github.com"},MaxAge: 12 * time.Hour,}))
//New 函数接收配置项,返回一个用户自定义的 CORS 中间件,绑定到路由中。

配置项说明:

  • AllowAllOrigins bool 允许所有请求源。
  • AllowOrigins []string 指定允许请求源的列表,如果列表中存在 *,则允许所有请求源,默认值是 []
  • AllowOriginFunc func(origin string) bool 接收参数 origin,函数体中的验证逻辑返回是否允许跨域请求。该配置项优先级高于 AllowOrigins []string,如果设置该配置项,AllowOrigins []string 配置项的设置被忽略。
  • AllowMethods []string 允许的请求方式,默认值是 GETPOSTPUTPATCHDELETEHEAD,和 OPTIONS
  • AllowHeaders []string 用在对预请求的响应中,指示实际的请求中可以使用哪些 HTTP 请求头。
  • AllowCredentials bool 表示请求附带请求凭据时是否响应请求,例如 cookieHTTP authentication 或客户端 SSL 证书。
  • ExposeHeaders []string 可以在响应中显示的请求头。
  • MaxAge time.Duration 指示预请求的结果能被缓存多久。
  • AllowWildcard bool 添加请求源是否允许使用通配符,例如 http://some-domain/*https://api.http://some.*.subdomain.com
  • AllowBrowserExtensions bool 允许使用常用的浏览器的扩展模式。
  • AllowWebSockets bool 允许使用 WebSocket 协议。
  • AllowFiles bool 允许使用 file:// 协议。
  • DefaultConfig方式

默认设置一些通用配置项,我们可以直接使用,也可以在此基础上添加我们需要的其他配置项。

func DefaultConfig() Config {return Config{AllowMethods:     []string{"GET", "POST", "PUT", "PATCH", "DELETE", "HEAD", "OPTIONS"},AllowHeaders:     []string{"Origin", "Content-Length", "Content-Type"},AllowCredentials: false,MaxAge:           12 * time.Hour,}
}
  • Default方式

DefaultConfig 方式的基础上,设置 AllowAllOrigins 选项为 true,因为 DefaultConfig 方式默认不允许任意请求源,所以需要单独设置 AllowAllOrigins 选项为 true

func Default() gin.HandlerFunc {config := DefaultConfig()config.AllowAllOrigins = truereturn New(config)
}

3、某段配置代码分析

//设置cors中间件
func Cors() gin.HandlerFunc {return func(c *gin.Context) {method := c.Request.Method  //获取请求包的http请求方法origin := c.Request.Header.Get("Origin") //获取请求包的head头的Origin参数值var headerkeys []stringfor k := range c.Request.Header {headerkeys = append(headerkeys, k)}headerStr := strings.Join(headerkeys, ", ") //将请求包中head头部分的参数用","连接成字符串//检查请求头不为空if headerStr != "" {//如果请求头不为空,将请求头的键名添加到一个字符串中,以便在设置响应头时包含这些键名。headerStr = fmt.Sprintf("access-control-allow-origin, access-control-allow-headers,%s", headerStr)} else {headerStr = "access-control-allow-origin, access-control-allow-headers"}//检查请求头中origin是否为空if origin != "" {//设置响应头中的"Access-Control-Allow-Origin"字段,允许任何域名访问资源(这是一个简单的CORS策略,实际应用中可能需要更严格的控制)。c.Writer.Header().Set("Access-Control-Allow-Origin", "*")c.Header("Access-Control-Allow-Methods", "POST,GET,OPTIONS,PUT,DELETE, UPDATE")c.Header("Access-Control-Allow-Headers", "Authorization, Content-Length, X-CSRF-Token, Token,session,X_Requested_With,Accept, Origin, Host, Connection, Accept-Encoding, Accept-Language,DNT, X-CustomHeader, Keep-Alive, User-Agent, X-Requested-With, If-Modified-Since, Cache-Control, Content-Type, Pragma")c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers,Cache-Control,Content-Language,Content-Type,Expires,Last-Modified,Pragma,FooBar") // 跨域关键设置 让浏览器可以解析c.Header("Access-Control-Max-Age", "172800")                                                                                                                                                           // 缓存请求信息 单位为秒c.Header("Access-Control-Allow-Credentials", "false")                                                                                                                                                  //  跨域请求是否需要带cookie信息 默认设置为truec.Set("content-type", "application/json")                                                                                                                                                              // 设置返回格式是json}//放行所有OPTIONS方法if method == "OPTIONS" {c.JSON(http.StatusOK, "Options Request!")}}
}

相关文章:

用go实现cors中间件

目录 一、概述 二、简单请求和预检请求 简单请求 预检请求 三、使用go的gin框架实现cors配置 1、安装 2、函数 一、概述 CORS(Cross-Origin Resource Sharing)是一种浏览器安全机制,用于控制在Web应用程序中不同源(Origin&a…...

Linux 链表示例 LIST_INIT LIST_INSERT_HEAD

list(3) — Linux manual page 用Visual Studio 2022创建CMake项目 * CmakeLists.txt # CMakeList.txt : Top-level CMake project file, do global configuration # and include sub-projects here. # cmake_minimum_required (VERSION 3.12)project ("llist")# I…...

【机器学习】详解回归(Regression)

文章目录 是什么的问题案例说明 是什么的问题 回归分析(Regression Analysis) 是研究自变量与因变量之间数量变化关系的一种分析方法,它主要是通过因变量Y与影响它的自变量 X i ( i 1 , 2 , 3 … ) X_i(i1…...

mac 配置 httpd nginx php-fpm 详细记录 已解决

在日常mac电脑 开发php项目一直是 httpd 方式 运行,由于有 多版本 运行的需求,docker不想用,索性用 php-fpm进行 功能处理。上次配置 是好的,但是感觉马马虎虎,这次 配置底朝天。因为配置服务器,几乎也都是…...

Angular 项目升级需要注意什么?

升级Angular项目是一个重要的任务,因为它可以帮助你获得新的功能、性能改进和安全性增强。然而,Angular的版本升级可能会涉及到一些潜在的问题和挑战。以下是升级Angular项目时需要注意的一些重要事项: 备份项目:在升级之前&…...

开发高性能知识付费平台:关键技术策略

引言 在构建知识付费平台时,高性能是确保用户满意度和平台成功的关键因素之一。本文将探讨一些关键的技术策略,帮助开发者打造高性能的知识付费平台。 1. 前端性能优化 使用CDN加速资源加载 使用内容分发网络(CDN)来托管和加…...

python图像匹配:如何使用Python进行图像匹配

Python图像匹配是指使用Python编写的程序来进行图像匹配。它可以在两幅图像之间找到相似的部分,从而实现图像检索、图像比较、图像拼接等功能。 Python图像匹配是指使用Python编写的程序来进行图像匹配。它可以在两幅图像之间找到相似的部分,从而实现图…...

R语言绘制PCA双标图、碎石图、变量载荷图和变量贡献图

1、原论文数据双标图 代码&#xff1a; setwd("D:/Desktop/0000/R") #更改路径#导入数据 df <- read.table("Input data.csv", header T, sep ",")# ----------------------------------- #所需的包: packages <- c("ggplot2&quo…...

Jolokia 笔记 (Kafka/start/stop)

目录 1. Jolokia 笔记 (Kafka/start/stop) 1. Jolokia 笔记 (Kafka/start/stop) java -javaagent:agent.jarport8778,hostlocalhostJolokia 是作为 Kafka 的 Java agent, 基于 HTTP 协议提供了一个使用 JSON 作为数据格式的外部接口, 提供给 DataKit 使用。 Kafka 启动时, 先配…...

Qt5开发及实例V2.0-第十九章-Qt.QML编程基础

Qt5开发及实例V2.0-第十九章-Qt.QML编程基础 第19章 QML编程基础19.1 QML概述19.1.1 第一个QML程序19.1.2 QML文档构成19.1.3 QML基本语法 19.2 QML可视元素19.2.1 Rectangle&#xff08;矩形&#xff09;元素19.2.2 Image&#xff08;图像&#xff09;元素19.2.3 Text&#xf…...

固定开发板的ifconfig的IP地址

背景 由于我是使用vsocode的ssh插件远程连接我的开发板, 所以我每次开机就要重新连上屏幕看一下这个ifconfig的ip地址然后更改我的ssh config文件 这里提供一个使用nmcli设置静态IP的方法 请确保使用你的实际连接名称替换Wi-Fi connection 1 使用nmcli设置静态IP相对直接&a…...

停车场系统源码

源码下载地址&#xff08;小程序开源地址&#xff09;&#xff1a;停车场系统小程序&#xff0c;新能源电动车充电系统&#xff0c;智慧社区物业人脸门禁小程序: 【涵盖内容】&#xff1a;城市智慧停车系统&#xff0c;汽车新能源充电&#xff0c;两轮电动车充电&#xff0c;物…...

R语言贝叶斯MCMC:GLM逻辑回归、Rstan线性回归、Metropolis Hastings与Gibbs采样算法实例...

原文链接&#xff1a;http://tecdat.cn/?p23236 在频率学派中&#xff0c;观察样本是随机的&#xff0c;而参数是固定的、未知的数量&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频 什么是频率学派&#xff1f; 概率被解释为一个随机过程的许多观测…...

若依前后端分离如何解决匿名注解启动报错?

SpringBoot2.6.0默认是ant_path_matcher解析方式,但是2.6.0之后默认是path_pattern_parser解析方式。 所以导致读取注解类方法需要对应的调整,当前若依项目默认版本是2.5.x,如果使用大于2.6.x,需要将info.getPatternsCondition().getPatterns()修改为info.getPathPatterns…...

Spring面试题4:面试官:说一说Spring由哪些模块组成?说一说JDBC和DAO之间的联系和区别?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:说一说Spring由哪些模块组成? Spring是一个开源的Java框架,由多个模块组成,每个模块都提供不同的功能和特性。下面是Spring框架的主要模块: S…...

【再识C进阶3(上)】详细地认识字符串函数、进行模拟字符串函数以及拓展内容

小编在写这篇博客时&#xff0c;经过了九一八&#xff0c;回想起了祖国曾经的伤疤&#xff0c;勿忘国耻&#xff0c;振兴中华&#xff01;加油&#xff0c;逐梦少年&#xff01; 前言 &#x1f493;作者简介&#xff1a; 加油&#xff0c;旭杏&#xff0c;目前大二&#xff0c;…...

docker启动mysql8目录挂载改动

5.7版本&#xff1a; 拉取mysql镜像 docker pull mysql:5.7启动 docker run -p 3306:3306 --name mysql5 \ -v /Users/zhaosichun/data/dockerData/log:/var/log/mysql \ -v /Users/zhaosichun/data/dockerData/data:/var/lib/mysql \ -v /Users/zhaosichun/data/dockerData…...

CHATGPT中国免费网页版有哪些-CHATGPT中文版网页

CHATGPT中国免费网页版&#xff0c;一个强大的人工智能聊天机器人。如果你曾经感到困惑、寻求答案&#xff0c;或者需要一些灵感&#xff0c;那么CHATGPT国内网页版可能会成为你的好朋友。 CHATGPT国内免费网页版&#xff1a;你的多面“好朋友” 随着人工智能技术的不断发展&a…...

docker network create命令

docker network create命令用于创建一个新的网络连接。 DRIVER接受内置网络驱动程序的桥接或覆盖。如果安装了第三方或自己的自定义网络驱动程序&#xff0c;则可以在此处指定DRIVER。 如果不指定--driver选项&#xff0c;该命令将为您自动创建一个桥接网络。 当安装Docker Eng…...

4G版本云音响设置教程腾讯云平台版本

文章目录 4G本云音响设置教程介绍一、申请设备三元素1.腾讯云物联网平台2.创建产品3.设置产品参数4.添加设备5.获取三元素 二、设置设备三元素1.打开MQTTConfigTools2.计算MQTT参数3.使用USB连接设备4.设置参数 三、腾讯云物联网套件协议使用说明1.推送协议信息2.topic规则说明…...

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

C# SqlSugar:依赖注入与仓储模式实践

C# SqlSugar&#xff1a;依赖注入与仓储模式实践 在 C# 的应用开发中&#xff0c;数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护&#xff0c;许多开发者会选择成熟的 ORM&#xff08;对象关系映射&#xff09;框架&#xff0c;SqlSugar 就是其中备受…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

十九、【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建

【用户管理与权限 - 篇一】后端基础:用户列表与角色模型的初步构建 前言准备工作第一部分:回顾 Django 内置的 `User` 模型第二部分:设计并创建 `Role` 和 `UserProfile` 模型第三部分:创建 Serializers第四部分:创建 ViewSets第五部分:注册 API 路由第六部分:后端初步测…...

stm32wle5 lpuart DMA数据不接收

配置波特率9600时&#xff0c;需要使用外部低速晶振...