Go语言实现CORS需精确匹配Origin并显式声明响应头:允许特定域名时设Access-Control-Allow-Origin为该域名;携带凭证时必须禁用通配符、启用AllowCredentials且Origin严格匹配;推荐使用rs/cors库自动处理预检与校验。

在 Go 语言中实现跨域资源共享(CORS),关键是在 HTTP 响应头中正确设置 Access-Control-Allow-Origin 等字段,并只允许你信任的指定域名,而非使用通配符 *(尤其当携带凭证时不可用)。
明确允许特定域名(不带凭证)
如果前端请求不携带 Cookie 或 Authorization 头(即 credentials: false),可直接在响应头中写死目标域名:
- 检查请求头中的
Origin是否在白名单内(如https://example.com) - 若匹配,设置
Access-Control-Allow-Origin: https://example.com - 同时建议设置
Access-Control-Allow-Methods和Access-Control-Allow-Headers
示例(使用标准 net/http):
func corsMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
allowedOrigins := []string{"https://example.com", "https://admin.example.org"}
isAllowed := false
for _, o := range allowedOrigins {
if origin == o {
isAllowed = true
break
}
}
if isAllowed {
w.Header().Set("Access-Control-Allow-Origin", origin)
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization")
}
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusOK)
return
}
next.ServeHTTP(w, r)
})
}
支持携带凭证的跨域请求
当前端设置 credentials: true(例如发送 Cookie 或 Bearer Token),Access-Control-Allow-Origin **不能为 ***,且必须精确匹配 Origin。同时需显式开启:
立即学习“go语言免费学习笔记(深入)”;
Access-Control-Allow-Credentials: true- 确保
Access-Control-Allow-Origin是单个具体域名(如https://app.example.com) -
浏览器会拒绝
Origin: https://app.example.com但Allow-Origin: *的响应
注意:此时无法用通配子域(如 https://*.example.com),需手动比对或使用正则(谨慎验证)。
使用第三方库简化处理(推荐)
用 rs/cors 库可更安全、灵活地管理策略:
import "github.com/rs/cors"
handler := cors.New(cors.Options{
AllowedOrigins: []string{"https://example.com", "https://dashboard.example.net"},
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
AllowedHeaders: []string{"Content-Type", "Authorization"},
ExposedHeaders: []string{"X-Total-Count"},
AllowCredentials: true,
}).Handler(yourMux)
它自动处理预检(OPTIONS)、Origin 校验、Header 注入,避免手写逻辑出错。
常见陷阱与注意事项
- 不要在生产环境返回
Access-Control-Allow-Origin: *同时设AllowCredentials: true—— 这会导致浏览器直接拦截 - 确保反向代理(如 Nginx)未覆盖或删除你的 CORS 响应头
- 开发时可用浏览器开发者工具的 Network 面板查看请求/响应头,确认
Origin和Allow-Origin是否一致 - 若后端部署在子路径(如
/api/v1),CORS 配置与路由无关,只取决于 HTTP 请求头
不复杂但容易忽略细节,核心就是“精确匹配 + 显式声明 + 拒绝默认通配”。










