go-zero网关需手动配置CORS中间件,否则跨域请求被拦截;须初始化allowedOrigins非nil、处理OPTIONS预检、禁止Credentials为true时用*通配Origin,并在入口完整注册四步流程。

在go-zero网关中处理前端跨域请求时,必须显式配置CORS中间件,因为框架原生不支持开箱即用的跨域配置,否则浏览器会拦截所有非同源AJAX请求,导致接口调用失败、状态码显示为“CORS error”而非真实HTTP错误。
创建基础CORS中间件
新建 middleware/cors.go 文件,定义结构体与核心处理逻辑:
package middleware
import "net/http"
type CorsMiddleware struct {
allowedOrigins []string
allowedMethods string
allowedHeaders string
}
func NewCorsMiddleware() *CorsMiddleware {
return &CorsMiddleware{
allowedOrigins: []string{"*"},
allowedMethods: "GET, POST, PUT, DELETE, OPTIONS, PATCH",
allowedHeaders: "Content-Type, X-CSRF-Token, Authorization, AccessToken, Token, Accept",
}
}
这一步不能省略结构体字段初始化——若直接传空切片或空字符串,【allowedOrigins为nil时会导致Access-Control-Allow-Origin头被忽略,跨域彻底失效】。
实现Handle方法并注入响应头
在同一个文件中补全 Handle 方法:
func (m *CorsMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
setHeader(w, m)
if r.Method == "OPTIONS" {
w.WriteHeader(http.StatusNoContent)
return
}
next(w, r)
}
}
func setHeader(w http.ResponseWriter, m *CorsMiddleware) {
origin := r.Header.Get("Origin")
if len(m.allowedOrigins) == 1 && m.allowedOrigins[0] == "*" {
w.Header().Set("Access-Control-Allow-Origin", "*")
} else {
for _, o := range m.allowedOrigins {
if o == origin {
w.Header().Set("Access-Control-Allow-Origin", origin)
break
}
}
}
w.Header().Set("Access-Control-Allow-Methods", m.allowedMethods)
w.Header().Set("Access-Control-Allow-Headers", m.allowedHeaders)
w.Header().Set("Access-Control-Expose-Headers", "Content-Length, Content-Type, X-Total-Count")
w.Header().Set("Access-Control-Allow-Credentials", "true")
}
注意:Access-Control-Allow-Credentials设为true时,【Access-Control-Allow-Origin不能为*,否则浏览器将拒绝响应】。开发阶段可临时用*调试,上线前必须改为具体域名列表。
在网关入口注册中间件
打开网关主文件(如 gateway/main.go),定位到路由注册位置:
第一步:导入 middleware 包
第二步:在 server := zrpc.MustNewServer(...) 后添加中间件实例化:
corsMw := middleware.NewCorsMiddleware()
第三步:将 corsMw.Handle 封装进 HTTP handler 链:
http.Handle("/xxx", corsMw.Handle(yourHandler))
第四步:确保 OPTIONS 请求路径也被覆盖——若使用 go-zero 的 rest.Router,需显式注册:
r.SetOptionsHandler(func(w http.ResponseWriter, r *http.Request) {
corsMw.Handle(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})).ServeHTTP(w, r)
})
这四步缺一不可。漏掉第四步会导致部分预检请求未命中中间件,浏览器报错“Response to preflight request doesn’t pass access control check”。


















