Go Buf Connect gRPC服务器CORS配置问题求助
问题诊断与修复
核心错误点
- CORS中间件作用范围错误:你当前仅将CORS中间件应用在单个gRPC接口handler上,但预检请求(OPTIONS)会先经过mux路由匹配,若未全局包裹mux,非接口路径的请求(或路由匹配前的请求)无法触发CORS逻辑。
- AllowedMethods未包含OPTIONS:浏览器预检请求使用OPTIONS方法,你的配置里没有允许该方法,导致rs/cors无法正确响应预检。
- 测试路径错误:你测试的是根路径
/,但实际gRPC接口注册在特定子路径(比如你打印的Path of Handler对应的路径),根路径本身没有handler,返回404是正常的,但这不是你的CORS问题所在。
修复后的代码
package wavserver import ( "context" "fmt" "net/http" "github.com/jmoiron/sqlx" "github.com/pienaahj/recordingdepo/backend/gen/wavapi/v1/wavapiv1connect" li "github.com/pienaahj/recordingdepo/backend/logwrapper" "github.com/rs/cors" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" ) type wavapiServer struct { Repo *sqlx.DB } // RunServer is the main gprs server func RunServer(ctx context.Context, repo *sqlx.DB) error { fmt.Println("message from runserver, repo received: ", repo) CallFrom := "Call from GRPC main" var port string = ":50051" var success int = 204 recorder := &wavapiServer{ Repo: repo, } // create a new mux mux := http.NewServeMux() // setup the recordings service handler path, handler := wavapiv1connect.NewRecordingsServiceHandler(recorder) fmt.Println("Path of Handler: ", path) // 注册handler到mux mux.Handle(path, handler) // 配置CORS c := cors.New(cors.Options{ AllowedHeaders: []string{ "Content-Type", "Connect-Protocol-Version", "Connect-Timeout-Ms", "Grpc-Timeout", "X-Grpc-Web", "X-User-Agent", "Authorization", // 可选:如果需要带认证头可以加上 }, AllowedOrigins: []string{"http://localhost:3000"}, AllowCredentials: true, AllowedMethods: []string{"POST", "GET", "OPTIONS"}, // 必须包含OPTIONS Debug: true, // disable for production OptionsPassthrough: false, // 改为false,让rs/cors处理OPTIONS请求 OptionsSuccessStatus: success, }) // 将CORS中间件全局包裹整个mux,而非单个handler wrappedMux := c.Handler(mux) // 启动服务器 err := http.ListenAndServe( port, // Use h2c so we can serve HTTP/2 without TLS. h2c.NewHandler(wrappedMux, &http2.Server{}), ) if err != nil { li.Logger.ErrGRPCListenerMessage(CallFrom, err) fmt.Printf("Failed to listen and serve on gPRC server: %v\n", err) return err } return nil }
关键修改说明
- 全局包裹mux:将CORS中间件应用到整个mux上,确保所有请求(包括预检OPTIONS)都经过CORS处理。
- 添加OPTIONS到AllowedMethods:明确允许预检请求使用的OPTIONS方法。
- 关闭OptionsPassthrough:让rs/cors自行处理OPTIONS请求,避免传递给后续handler导致404。
正确的测试命令
使用你打印的Path of Handler路径(比如假设是/wavapi.v1.RecordingsService/ListRecordings)来发送预检请求:
curl -X OPTIONS -i -H 'Origin: http://localhost:3000' http://localhost:50051/你的接口路径
例如,如果你的接口路径是/wavapi.v1.RecordingsService/GetRecording,则测试命令为:
curl -X OPTIONS -i -H 'Origin: http://localhost:3000' http://localhost:50051/wavapi.v1.RecordingsService/GetRecording
此时应该返回包含正确CORS头的204响应,而非404。
内容的提问来源于stack exchange,提问作者Hendrik
相关产品推荐
相关产品推荐

