0


【Golang】Gin框架中跨域问题解决方案

在这里插入图片描述

✨✨ 欢迎大家来到景天科技苑✨✨

🎈🎈 养成好习惯,先赞后看哦~🎈🎈

🏆 作者简介:景天科技苑
🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。
🏆《博客》:Python全栈,Golang开发,PyQt5和Tkinter桌面开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi,flask等框架,云原生K8S,linux,shell脚本等实操经验,网站搭建,数据库等分享。

所属的专栏:Go语言开发零基础到高阶实战
景天的主页:景天科技苑

在这里插入图片描述

文章目录

Gin框架中跨域问题解决方案

一、引言

在使用Go语言进行Web开发时,Gin框架因其简洁、高效的特点而被广泛使用。然而,在实际开发中,跨域问题(CORS, Cross-Origin Resource Sharing)是一个常见的挑战。跨域问题主要源于浏览器的同源策略(Same-Origin Policy),当一个网页尝试从不同的源(协议、域名或端口不同)请求资源时,就会产生跨域问题。本文将结合实际案例,详细介绍在Gin框架中解决跨域问题的多种方法。

二、跨域问题的基本概念

1. 同源策略

同源策略是浏览器的一种安全机制,用于限制一个源(协议、域名和端口)的文档或脚本如何与另一个源的资源进行交互。例如,一个在http://example.com上的网页不能从http://otherdomain.com加载数据,即使服务器响应了请求,浏览器也会阻止该请求返回的数据被脚本访问。

同源策略,是浏览器为了保护用户信息安全的一种安全机制。
所谓的同源就是指代通信的两个地址(例如服务端接口地址与浏览器客户端页面地址)之间比较,是否协议、域名和端口相同。
不同源的客户端脚本[javascript]在没有明确授权的情况下,没有权限读写对方信息。

同源策略机制(Same Origin Policy,SOP)是一种约定,它是浏览器最核心也是最基本的安全功能,如果缺少了同源策略。
则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础上的,浏览器只是针对同源策略的一种实现。

当一个浏览器的两个tab页中分别打开百度和谷歌的页面时,当浏览器的百度tab页执行一个脚本的时候会检查这个脚本是属于哪个页面的,即检查是否同源,只有和百度同源的脚本才会被执行。
如果非同源,那么在请求数据时,浏览器会在控制台中报一个异常,提示拒绝访问。
不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。所以google.com下的js脚本采用ajax读取baidu.com里面的文件数据是会报错的。

跨域请求,首先浏览器为了安全,做了一个同源策略机制,也就是所谓的同源安全策略,本质上,其实是不存在所谓的跨不跨域的,
把浏览器想象成一个发送网络请求的软件,按照道理来说,请求都是可以发送出去的,但是在 web 端,浏览器里,这么做的就不合适,
如果网络上的接口可以不受限制的被任意人调用,那将是一个非常混乱的场景,所以,为了防止这种情况,浏览器做了这个同源策略来防止这种情况发生。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
总结:协议相同+域名相同+端口号相同,浏览器才认为是同一个网站,才不会受到同源策略的影响,才可以正常的发送Ajax请求。

所谓的同源策略是浏览器实现的,而和后台服务器无关,A 发送请求到 B. 请求实际上是发送到了 B 后台, B后台接受到数据后。
其实也有返回,只不过,这个数据返回到浏览器之后,浏览器把这个数据给劫持了,不让A网站使用

既然跨域这么麻烦,为什么要进行跨域?
因为当一个项目变大时,把所有的内容都丢在一个网站或者是后台服务器中是不现实的.

2. 跨域资源共享(CORS)

CORS是一种标准机制,允许Web应用程序在跨域访问资源时,通过设置特定的HTTP响应头来放宽浏览器的同源策略限制。

3. 预检请求(Preflight Request)

预检请求是CORS机制中的一部分,它是浏览器为了安全考虑而自动发起的一种请求,主要用于复杂的跨域请求前的“探路”。这种请求使用HTTP的OPTIONS方法,目的是为了确认服务器是否允许特定的跨域请求。

三、Gin框架中解决跨域问题的方法

方法一:自定义中间件

在Gin框架中,可以通过自定义中间件的方式来解决跨域问题。以下是一个自定义中间件的示例代码:

package main

import("fmt""github.com/gin-gonic/gin""net/http""strings")// 跨域中间件funcCors() gin.HandlerFunc {returnfunc(c *gin.Context){
        method := c.Request.Method // 请求方法
        origin := c.Request.Header.Get("Origin")// 请求头部var headerKeys []string// 声明请求头keysfor k,_:=range c.Request.Header {
            headerKeys =append(headerKeys, k)}
        headerStr := strings.Join(headerKeys,", ")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"}if origin !=""{
            c.Writer.Header().Set("Access-Control-Allow-Origin","*")
            c.Header("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信息,默认设置为true
            c.Set("content-type","application/json")// 设置返回格式是json}// 放行所有OPTIONS方法if method =="OPTIONS"{
            c.JSON(http.StatusOK,"Options Request!")}// 处理请求
        c.Next()}}funcmain(){
    engine := gin.Default()// 允许使用跨域请求,全局中间件
    engine.Use(Cors())
    engine.Run(":11000")// 运行启动端口}

在上述代码中,定义了一个名为

Cors

的中间件函数,该函数通过设置HTTP响应头来允许跨域请求。在

main

函数中,通过

engine.Use(Cors())

将中间件应用到全局路由上。

方法二:使用第三方库

github.com/gin-contrib/cors

Gin框架自身并未内置CORS支持,但有一个官方推荐的、与Gin高度集成的第三方库

github.com/gin-contrib/cors

可以方便地解决这个问题。以下是使用第三方库解决跨域问题的步骤:

  1. 添加依赖: 在你的项目中添加github.com/gin-contrib/cors依赖:go get -u github.com/gin-contrib/cors
  2. 创建CORS配置: 创建一个cors.Config结构体实例,用于定义你的CORS策略。以下是一些常见的配置选项:package confimport("github.com/gin-contrib/cors""time")var CorsConfig = cors.Config{ AllowAllOrigins:false, AllowOrigins:[]string{"http://localhost:3000"},// 允许的源,生产环境中应替换为具体的允许域名 AllowOriginFunc:func(origin string)bool{returntrue},// 自定义函数来判断源是否允许 AllowMethods:[]string{"GET","POST","PUT","PATCH","DELETE","HEAD","OPTIONS"},// 允许的HTTP方法列表 AllowHeaders:[]string{"Origin","Content-Length","Content-Type","Authorization"},// 允许的HTTP头部列表 AllowCredentials:true,// 是否允许浏览器发送Cookie MaxAge:10* time.Minute,// 预检请求(OPTIONS)的缓存时间(秒)}
  3. 使用CORS中间件: 在Gin的路由器上应用CORS中间件:package mainimport("github.com/gin-contrib/cors""github.com/gin-gonic/gin""goproject/conf"// 引入CORS配置)funcmain(){ router := gin.Default()// 使用配置好的CORS规则 router.Use(cors.New(conf.CorsConfig))// 定义路由 router.GET("/ping",func(c *gin.Context){ c.JSON(200, gin.H{"message":"pong",})}) router.Run(":8080")// 启动服务器}

在上述代码中,首先定义了CORS配置

CorsConfig

,然后在Gin路由器上通过

router.Use(cors.New(conf.CorsConfig))

应用了CORS中间件。这样,所有经过这个路由器的请求都会先经过CORS中间件的处理,自动添加相应的CORS响应头。

方法三:JSONP请求(不推荐)

JSONP是一种较老的技术,用于解决跨域问题。然而,由于其安全性和灵活性不如CORS,现代浏览器已逐渐弃用JSONP。因此,在可能的情况下,建议优先考虑实现CORS。然而,如果你需要支持旧版客户端或CORS不可行的特定场景,JSONP仍可作为一种可行的解决方案。

以下是一个使用JSONP的示例代码:

package main

import("github.com/gin-gonic/gin")funcmain(){
    router := gin.Default()// JSONP请求处理
    router.GET("/jsonp",func(c *gin.Context){
        callback := c.Query("callback")
        data :=map[string]interface{}{"title":"标题-jsonp","desc":"说明-jsonp","content":"内容-jsonp",}
        c.JSONP(200, data)})

    router.Run(":8080")}

在上述代码中,定义了一个

/jsonp

路由,该路由通过

c.JSONP(200, data)

方法返回JSONP响应。客户端可以通过添加

callback

参数来接收JSONP响应。

四、总结

跨域问题是Web开发中的一个常见问题,特别是在前后端分离的项目中。在Gin框架中,处理跨域问题可以通过自定义中间件、使用第三方库或JSONP等方式来实现。其中,使用自定义中间件和第三方库是两种常见且有效的方法。通过合理配置CORS策略,可以确保Web应用程序能够正确处理跨域请求,同时保障用户数据的安全。

在实际应用中,开发者应根据具体的安全需求和交互模式来配置CORS策略。例如,可以限制允许跨域请求的域名、方法、头部等,以确保只有符合条件的请求能够被处理。此外,还需要注意处理预检请求,以确保复杂的跨域请求能够成功通过。

标签: golang gin 开发语言

本文转载自: https://blog.csdn.net/littlefun591/article/details/143160597
版权归原作者 景天科技苑 所有, 如有侵权,请联系我们删除。

“【Golang】Gin框架中跨域问题解决方案”的评论:

还没有评论