跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

Golang Web服务如何处理跨域请求_CORS处理方案汇总

Go Web服务需显式处理CORS,推荐用rs/cors中间件;手动设置易漏预检请求和凭证支持;Gin需禁用默认配置,显式指定AllowedOrigins与AllowCredentials;预检失败主因是无OPTIONS路由匹配。 Go Web 服务默认不处理 跨域 请求, 浏览器 会直接拦截
fetch
或
XMLHttpRequest
的响应( 状态码 看似 200,但控制台报
Blocked by CORS policy
)。必须显式添加
Access-Control-Allow-Origin
等响应头,且需覆盖预检(
OPTIONS
)请求。 使用
rs/cors
中间件最稳妥 这是社区事实标准,兼容
net/http
、
gin
、
echo
等主流框架,能正确处理简单请求和预检请求,避免手动漏掉
Access-Control-Allow-Headers
或
Access-Control-Max-Age
等关键头。 常见错误是只写
Access-Control-Allow-Origin: *
却没允许凭证(
withCredentials: true
),导致浏览器拒绝响应。此时必须指定具体域名,且需开启
AllowCredentials
:
import "github.com/rs/cors"

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) w.Write([]byte("ok")) })

// 允许带凭证的跨域请求 corsHandler := cors.New(cors.Options{ AllowedOrigins: []string{"https://www.php.cn/link/b05edd78c294dcf6d960190bf5bde635"}, AllowCredentials: true, AllowedHeaders: []string{"Content-Type", "Authorization", "X-Requested-With"}, }).Handler(handler)

http.ListenAndServe(":8080", corsHandler)

立即学习 “ go语言免费学习笔记(深入) ”; 注意:
AllowedOrigins
不能同时设为
*
和
AllowCredentials: true
,否则 Go 会 panic,浏览器也会拒绝。
net/http
手动加 Header 的陷阱 手动设置响应头看似简单,但极易出错。尤其容易忽略以下三点: 对
OPTIONS
请求不做处理,导致预检失败 未在所有 路由 统一设置,某些 handler 忘记写
w.Header().Set(...)
把
Access-Control-Allow-Origin
写成固定值却没校验
Origin
请求头,引发安全风险 若坚持手写,至少保证: Comet AI 浏览器 下载 Comet AI 浏览器,体验由 Perplexity AI 驱动的革命性上网方式。内置 AI 助手可实时总结网页、跨标签页对比信息、自动执行任务。告别繁琐操作,让 AI 成为你的浏览副驾,大幅提升研究与工作效率。支持 Windows、macOS、Android 和 iOS。 下载
func corsMiddleware(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { origin := r.Header.Get("Origin") if origin != "" { 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") w.Header().Set("Access-Control-Expose-Headers", "X-Total-Count") w.Header().Set("Access-Control-Allow-Credentials", "true") }
    if r.Method == "OPTIONS" {
        w.WriteHeader(http.StatusOK)
        return
    }

    next.ServeHTTP(w, r)
})
} Gin 框架的
Cors()
配置要点 Gin 自带
github.com/gin-contrib/cors
,但默认配置(如
cors.Default()
)仅适用于开发环境。生产中必须显式控制
AllowedOrigins
和
AllowCredentials
:
cors.Default()
允许任意源 +
*
,但禁用凭证,无法用于登录态保持
cors.Config{AllowAllOrigins: true}
同样禁止
AllowCredentials: true
必须用
AllowedOrigins
列表 +
AllowCredentials: true
组合,并确保 前端
fetch
设置
credentials: 'include'
示例:
import "github.com/gin-contrib/cors"

r := gin.Default() r.Use(cors.New(cors.Config{ AllowedOrigins: []string{"https://www.php.cn/link/c5e212421256cf0dcf335940944bc162"}, AllowCredentials: true, AllowHeaders: []string{"Content-Type", "Authorization"}, ExposeHeaders: []string{"X-Total-Count"}, MaxAge: 24 * time.Hour, }))

预检请求(
OPTIONS
)为什么总被 404? 根本原因是:没有路由匹配到
OPTIONS
方法。Gin 默认不注册
OPTIONS
路由;
net/http
的
ServeMux
也不自动响应;即使写了
router.OPTIONS("/api/user", ...)
,中间件也可能未生效。 解决方式只有两个: 用
rs/cors
或
gin-contrib/cors
—— 它们会在内部拦截并响应预检 手动注册通配
OPTIONS
路由(不推荐):
r.OPTIONS("/*path", func(c *gin.Context) {})
,但需确保它在所有中间件链最前 别试图在 handler 里用
if r.Method == "OPTIONS"
就返回,那只能覆盖当前路由,无法解决全站预检问题。

相关文章