Vue3前端调用Go gRPC-Gateway时的CORS跨域问题求助
解决gRPC-Gateway + Go后端的CORS跨域问题
你的问题核心是浏览器发送的OPTIONS预检请求未被正确处理——之前的CORS中间件仅设置了响应头,但未直接处理OPTIONS请求,导致预检请求被转发到gRPC网关后,返回的响应缺少必要的CORS头,触发跨域拦截。
正确的CORS中间件实现
修改enableCors函数,专门处理OPTIONS预检请求,直接返回200状态码和完整的CORS头:
func enableCors(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // 允许前端源(根据实际前端地址调整) w.Header().Set("Access-Control-Allow-Origin", "http://localhost:9000") // 允许的HTTP方法 w.Header().Set("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD") // 允许的请求头(包含gRPC-Gateway常用的头字段) w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization, Grpc-Metadata-*") // 允许携带Cookie等凭证(如果前端需要) w.Header().Set("Access-Control-Allow-Credentials", "true") // 拦截OPTIONS预检请求,直接返回成功 if r.Method == http.MethodOptions { w.WriteHeader(http.StatusOK) return } // 非OPTIONS请求,继续转发到gRPC网关处理 h.ServeHTTP(w, r) }) }
正确应用中间件
在RunHttpServer函数中,用enableCors包装你的swMux后再赋值给server.Handler:
// 替换原来的 server.Handler = swMux server.Handler = enableCors(swMux)
为什么之前的方法无效?
浏览器发起跨域请求前会先发送OPTIONS预检请求,验证后端是否允许跨域。你之前的中间件只是设置头后继续转发请求,但gRPC网关本身没有处理OPTIONS请求的路由,所以返回的响应没有CORS头,导致浏览器拦截。现在的实现直接拦截OPTIONS请求,返回符合要求的响应,解决了预检问题。
可选:灵活配置允许的源
如果需要允许多个前端源,可以动态检查请求的Origin头:
allowedOrigins := map[string]bool{ "http://localhost:9000": true, "https://your-production-domain.com": true, } origin := r.Header.Get("Origin") if allowedOrigins[origin] { w.Header().Set("Access-Control-Allow-Origin", origin) }
内容的提问来源于stack exchange,提问作者Mike3355
相关产品推荐
相关产品推荐

