Golang 实现跨域请求的多种实现对比

 更新时间:2025年05月26日 10:10:40   作者:纸鸢666  
本文主要介绍了Golang 实现跨域请求的多种实现对比,包括原生设置、第三方库、框架中间件、反向代理,具有一定的参考价值,感兴趣的可以了解一下

1. 原生 net/http 手动设置 CORS 头

通过原生库手动设置 HTTP 响应头,处理 OPTIONS 预检请求。

实现示例:

func CORS(c *gin.Context) {
	c.Writer.Header().Set("Access-Control-Allow-Origin", "*")
	c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
	c.Writer.Header().Set("Access-Control-Allow-Headers", "Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, accept, origin, Cache-Control, X-Requested-With")
	c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")

	if c.Request.Method == "OPTIONS" {
		c.AbortWithStatus(http.StatusNoContent)
		return
	}

	c.Next()
}  

func main() {  
	r := gin.Default()  
	r.Use(CORS)  
  
	r.GET("/ping", func(c *gin.Context) {  
		c.JSON(200, gin.H{  
			"message": "pong",  
		})  
	})  
  
	r.Run(":8080")  
}  

优点:

  • 零依赖:无需引入第三方库。

  • 完全控制:可自定义所有 CORS 相关头信息。

缺点:

  • 冗余代码:需在每个路由中重复设置头信息。

  • 易出错:手动处理 OPTIONS 预检请求可能遗漏细节(如动态 Origin 校验)。

  • 维护困难:复杂场景(如多域名白名单)需要自行实现逻辑。

适用场景:简单项目或少量 API 端点。

2. 使用第三方库 rs/cors

通过流行的开源库 GitHub - rs/cors: Go net/http configurable handler to handle CORS requests 简化 CORS 配置。

实现示例:

package main

import (
    "net/http"
    "github.com/rs/cors"
)

func main() {
    mux := http.NewServeMux()
    mux.HandleFunc("/api", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte("Hello, CORS!"))
    })

    // 配置 CORS
    c := cors.New(cors.Options{
        AllowedOrigins:   ["https://example.com", "http://localhost:3000"],
        AllowedMethods:   ["GET", "POST", "PUT", "DELETE"],
        AllowedHeaders:   ["Content-Type", "Authorization"],
        AllowCredentials: true,
        Debug:            false,
    })

    handler := c.Handler(mux)
    http.ListenAndServe(":8080", handler)
}

优点:

  • 开箱即用:自动处理 OPTIONS 预检请求和头信息。

  • 灵活配置:支持域名白名单、HTTP 方法、自定义头等。

  • 安全可靠:内置动态 Origin 校验和凭据(Cookies)支持。

缺点:

  • 引入依赖:需管理第三方库版本。

适用场景:大多数项目,尤其是需要复杂 CORS 配置的情况。

3. Web 框架中间件(如 Gin、Echo)

主流 Web 框架(如 Gin、Echo)通常内置或提供 CORS 中间件。

Gin 框架示例:

package main

import (
    "github.com/gin-contrib/cors"
    "github.com/gin-gonic/gin"
)

func main() {
    r := gin.Default()
    
    // 配置 CORS 中间件
    r.Use(cors.New(cors.Config{
        AllowOrigins:     ["https://example.com"],
        AllowMethods:     ["GET", "POST"],
        AllowHeaders:     ["Content-Type"],
        ExposeHeaders:    ["Content-Length"],
        AllowCredentials: true,
        MaxAge: 12 * time.Hour,
    }))
    
    r.GET("/api", func(c *gin.Context) {
        c.String(200, "Hello, CORS!")
    })
    
    r.Run(":8080")
}

优点:

  • 框架集成:与路由、中间件等无缝协作。

  • 简化配置:语法与框架风格一致,通常比原生更简洁。

缺点:

  • 框架绑定:仅适用于特定框架(如 Gin、Echo)。

适用场景:已使用特定 Web 框架的项目。

4. 反向代理层处理(如 Nginx)

在反向代理(如 Nginx)中设置 CORS 头,无需修改 Go 代码。

Nginx 配置示例:

location /api {
    add_header 'Access-Control-Allow-Origin' 'https://example.com';
    add_header 'Access-Control-Allow-Methods' 'GET, POST';
    add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
    
    if ($request_method = OPTIONS) {
        return 204;
    }
    
    proxy_pass http://localhost:8080;
}

优点:

  • 解耦业务代码:跨域与业务逻辑分离。

  • 集中管理:适合微服务架构统一配置。

缺点:

  • 依赖运维:需熟悉 Nginx 配置,不适合无代理的小型项目。

适用场景:已有反向代理层或需要统一管理 CORS 的环境。

对比与选型建议

方式维护成本灵活性依赖项适用场景
原生手动设置简单 API、快速原型
rs/cors 库中高第三方库大多数项目
Web 框架中间件框架已使用对应框架的项目
反向代理(如 Nginx)运维环境微服务、已有代理层的项目

推荐选择:

  • 快速开发:优先使用 rs/cors 或框架中间件。

  • 复杂企业级:结合反向代理和中间件,实现多层控制。

  • 极简场景:原生手动设置(但需注意安全风险)。

关键注意事项

  • 安全限制:避免滥用 Access-Control-Allow-Origin: *,应指定明确的白名单。

  • 预检请求:确保正确处理 OPTIONS 方法,否则复杂请求(如带自定义头的 POST)会失败。

  • 凭据(Cookies):若需跨域传递 Cookies,需设置 AllowCredentials: true 并明确指定 Origin(不能为 *)。

通过合理选择跨域方案,可以在安全性和开发效率之间取得平衡。

到此这篇关于Golang 实现跨域请求的多种实现对比的文章就介绍到这了,更多相关Golang 跨域请求内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文带你理解Golang中的Time结构

    一文带你理解Golang中的Time结构

    根据golang的time包的文档可以知道,golang的time结构中存储了两种时钟,一种是Wall Clocks,一种是Monotonic Clocks,下面我们就来简单了解一下这两种结构吧
    2023-09-09
  • Go语言计算指定年月天数的方法

    Go语言计算指定年月天数的方法

    这篇文章主要介绍了Go语言计算指定年月天数的方法,实例分析了Go语言操作时间的技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • Go 代码块作用域变量遮蔽问题解析

    Go 代码块作用域变量遮蔽问题解析

    这篇文章主要为大家介绍了Go 代码块作用域变量遮蔽问题解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • Go 语言中的select语句详解及工作原理

    Go 语言中的select语句详解及工作原理

    在Go语言中,select语句是用于处理多个通道(channel)操作的一种控制结构,它类似于 switch 语句,本文给大家介绍Go 语言中的select语句详解及工作原理,感兴趣的朋友一起看看吧
    2025-04-04
  • Go语言学习笔记之文件读写操作详解

    Go语言学习笔记之文件读写操作详解

    这篇文章主要为大家详细介绍了Go语言对文件进行读写操作的方法,文中的示例代码讲解详细,对我们学习Go语言有一定的帮助,需要的可以参考一下
    2022-05-05
  • golang创建文件目录os.Mkdir,os.MkdirAll的区别说明

    golang创建文件目录os.Mkdir,os.MkdirAll的区别说明

    本文主要讲述os.Mkdir、os.MkdirAll区别以及在创建文件目录过程中的一些其他技巧,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-03-03
  • golang如何替换换行符

    golang如何替换换行符

    这篇文章主要介绍了golang如何替换换行符问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • Go的gin参数校验中的validator库详解

    Go的gin参数校验中的validator库详解

    这篇文章主要介绍了Go的gin参数校验之validator库,使用 validator 以后,只需要在定义结构体时使用 binding 或 validate tag标识相关校验规则,就可以进行参数校验了,而不用自己单独去写常见的校验规则,需要的朋友可以参考下
    2023-08-08
  • Go interface 接口的最佳实践经验分享

    Go interface 接口的最佳实践经验分享

    go 的接口在go的编程里面用的十分频繁,尤其是空接口的使用,因为有了接口,才使得Go语言变得异常的强大,今天给大家介绍下Go interface 接口的最佳实践经验分享,感兴趣的朋友一起看看吧
    2022-04-04
  • go protobuf 详解

    go protobuf 详解

    Protobuf是Protocol Buffers的简称,它是Google公司开发的一种数据描述语言,是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化,这篇文章主要介绍了protobuf 详解,需要的朋友可以参考下
    2024-01-01

最新评论