CORS跨域 #
一、CORS概述 #
1.1 什么是CORS #
CORS(Cross-Origin Resource Sharing)是一种机制,允许Web应用从不同域访问资源。
1.2 为什么需要CORS #
浏览器的同源策略限制了跨域请求,CORS允许服务器声明哪些源可以访问资源。
二、基本配置 #
2.1 使用内置中间件 #
go
package main
import (
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/cors"
)
func main() {
app := fiber.New()
// 默认配置(允许所有来源)
app.Use(cors.New())
app.Get("/", func(c *fiber.Ctx) error {
return c.JSON(fiber.Map{"message": "Hello"})
})
app.Listen(":3000")
}
2.2 自定义配置 #
go
app.Use(cors.New(cors.Config{
AllowOrigins: "https://example.com, https://api.example.com",
AllowMethods: "GET,POST,PUT,DELETE,OPTIONS",
AllowHeaders: "Content-Type,Authorization",
}))
三、完整配置 #
3.1 所有配置选项 #
go
app.Use(cors.New(cors.Config{
// 允许的来源
AllowOrigins: "https://example.com",
// 允许的方法
AllowMethods: "GET,POST,PUT,DELETE,OPTIONS",
// 允许的请求头
AllowHeaders: "Content-Type,Authorization,X-Requested-With",
// 允许携带凭证
AllowCredentials: true,
// 暴露的响应头
ExposeHeaders: "Content-Length,Content-Type",
// 预检请求缓存时间
MaxAge: 86400,
}))
3.2 允许所有来源 #
go
app.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowMethods: "GET,POST,PUT,DELETE,OPTIONS",
AllowHeaders: "Content-Type,Authorization",
}))
3.3 允许多个来源 #
go
app.Use(cors.New(cors.Config{
AllowOrigins: "https://example.com, https://app.example.com, http://localhost:3000",
AllowMethods: "GET,POST,PUT,DELETE",
AllowHeaders: "Content-Type,Authorization",
AllowCredentials: true,
}))
四、动态来源 #
4.1 动态验证来源 #
go
app.Use(cors.New(cors.Config{
AllowOriginsFunc: func(origin string) bool {
// 允许所有子域名
return strings.HasSuffix(origin, ".example.com") ||
origin == "http://localhost:3000"
},
AllowMethods: "GET,POST,PUT,DELETE",
}))
4.2 白名单验证 #
go
var allowedOrigins = map[string]bool{
"https://example.com": true,
"https://app.example.com": true,
"http://localhost:3000": true,
"http://localhost:8080": true,
}
app.Use(cors.New(cors.Config{
AllowOriginsFunc: func(origin string) bool {
return allowedOrigins[origin]
},
AllowMethods: "GET,POST,PUT,DELETE",
AllowCredentials: true,
}))
五、自定义CORS中间件 #
5.1 手动实现 #
go
func CORSMiddleware() fiber.Handler {
return func(c *fiber.Ctx) error {
origin := c.Get("Origin")
// 设置CORS头
c.Set("Access-Control-Allow-Origin", origin)
c.Set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
c.Set("Access-Control-Allow-Headers", "Content-Type,Authorization")
c.Set("Access-Control-Allow-Credentials", "true")
// 处理预检请求
if c.Method() == "OPTIONS" {
return c.SendStatus(204)
}
return c.Next()
}
}
5.2 带验证的CORS #
go
func SecureCORS(allowedOrigins []string) fiber.Handler {
return func(c *fiber.Ctx) error {
origin := c.Get("Origin")
// 验证来源
allowed := false
for _, o := range allowedOrigins {
if o == origin || o == "*" {
allowed = true
break
}
}
if allowed {
c.Set("Access-Control-Allow-Origin", origin)
c.Set("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS")
c.Set("Access-Control-Allow-Headers", "Content-Type,Authorization")
c.Set("Access-Control-Allow-Credentials", "true")
c.Set("Access-Control-Max-Age", "86400")
}
if c.Method() == "OPTIONS" {
return c.SendStatus(204)
}
return c.Next()
}
}
六、常见问题 #
6.1 预检请求失败 #
go
// 确保处理OPTIONS请求
app.Use(cors.New(cors.Config{
AllowOrigins: "*",
AllowMethods: "GET,POST,PUT,DELETE,OPTIONS",
AllowHeaders: "Content-Type,Authorization",
}))
// 或手动处理
app.Options("/*", func(c *fiber.Ctx) error {
return c.SendStatus(204)
})
6.2 凭证问题 #
go
// AllowCredentials为true时,AllowOrigins不能为"*"
app.Use(cors.New(cors.Config{
AllowOrigins: "https://example.com",
AllowCredentials: true,
}))
七、总结 #
7.1 CORS配置要点 #
| 配置 | 说明 |
|---|---|
| AllowOrigins | 允许的来源 |
| AllowMethods | 允许的方法 |
| AllowHeaders | 允许的请求头 |
| AllowCredentials | 允许凭证 |
| MaxAge | 预检缓存时间 |
7.2 下一步 #
现在你已经掌握了CORS跨域,接下来让我们学习 WebSocket,了解实时通信!
最后更新:2026-03-28