文章目录
- 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 端点。
- 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 配置的情况。
- 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 框架的项目。
- 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 的环境。
目录
- 1. 原生 net/http 手动设置 CORS 头
- 实现示例:
- 优点:
- 缺点:
- 2. 使用第三方库 rs/cors
- 实现示例:
- 优点:
- 缺点:
- 3. Web 框架中间件(如 Gin、Echo)
- Gin 框架示例:
- 优点:
- 缺点:
- 4. 反向代理层处理(如 Nginx)
- Nginx 配置示例:
- 优点:
- 缺点:
- 对比与选型建议
- 推荐选择:
- 关键注意事项
通过原生库手动设置 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 相关头信息。
零依赖:无需引入第三方库。
完全控制:可自定义所有 CORS 相关头信息。
-
冗余代码:需在每个路由中重复设置头信息。
-
易出错:手动处理 OPTIONS 预检请求可能遗漏细节(如动态 Origin 校验)。
-
维护困难:复杂场景(如多域名白名单)需要自行实现逻辑。
冗余代码:需在每个路由中重复设置头信息。
易出错:手动处理 OPTIONS 预检请求可能遗漏细节(如动态 Origin 校验)。
维护困难:复杂场景(如多域名白名单)需要自行实现逻辑。
适用场景:简单项目或少量 API 端点。
通过流行的开源库 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)支持。
开箱即用:自动处理 OPTIONS 预检请求和头信息。
灵活配置:支持域名白名单、HTTP 方法、自定义头等。
安全可靠:内置动态 Origin 校验和凭据(Cookies)支持。
-
引入依赖:需管理第三方库版本。
引入依赖:需管理第三方库版本。
适用场景:大多数项目,尤其是需要复杂 CORS 配置的情况。
主流 Web 框架(如 Gin、Echo)通常内置或提供 CORS 中间件。
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)。
框架绑定:仅适用于特定框架(如 Gin、Echo)。
适用场景:已使用特定 Web 框架的项目。
在反向代理(如 Nginx)中设置 CORS 头,无需修改 Go 代码。
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 配置,不适合无代理的小型项目。
依赖运维:需熟悉 Nginx 配置,不适合无代理的小型项目。
适用场景:已有反向代理层或需要统一管理 CORS 的环境。
| 方式 | 维护成本 | 灵活性 | 依赖项 | 适用场景 |
|---|---|---|---|---|
| 原生手动设置 | 高 | 高 | 无 | 简单 API、快速原型 |
rs/cors 库 |
低 | 中高 | 第三方库 | 大多数项目 |
| Web 框架中间件 | 低 | 中 | 框架 | 已使用对应框架的项目 |
| 反向代理(如 Nginx) | 中 | 中 | 运维环境 | 微服务、已有代理层的项目 |
-
快速开发:优先使用 rs/cors 或框架中间件。
-
复杂企业级:结合反向代理和中间件,实现多层控制。
-
极简场景:原生手动设置(但需注意安全风险)。
快速开发:优先使用 rs/cors 或框架中间件。
复杂企业级:结合反向代理和中间件,实现多层控制。
极简场景:原生手动设置(但需注意安全风险)。
-
安全限制:避免滥用 Access-Control-Allow-Origin: *,应指定明确的白名单。
-
预检请求:确保正确处理 OPTIONS 方法,否则复杂请求(如带自定义头的 POST)会失败。
-
凭据(Cookies):若需跨域传递 Cookies,需设置 AllowCredentials: true 并明确指定 Origin(不能为 *)。
安全限制:避免滥用 Access-Control-Allow-Origin: *,应指定明确的白名单。
预检请求:确保正确处理 OPTIONS 方法,否则复杂请求(如带自定义头的 POST)会失败。
凭据(Cookies):若需跨域传递 Cookies,需设置 AllowCredentials: true 并明确指定 Origin(不能为 *)。
通过合理选择跨域方案,可以在安全性和开发效率之间取得平衡。
到此这篇关于Golang 实现跨域请求的多种实现对比的文章就介绍到这了,更多相关Golang 跨域请求内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Go 跨域中间件解决CORS问题
- Golang多个域名的跨域资源共享的实现
- 使用Go语言实现跨域资源共享(CORS)设置
- Go Gin 处理跨域问题解决
- Go中跨域Cors中间件的实现
- go-micro微服务JWT跨域认证问题