发布于2026-07-13 阅读(0)
扫一扫,手机访问
先说几个核心判断:浏览器不能直接调用 gRPC,这不是配置层面的问题,而是协议层本身的硬限制——HTTP/2 + Protobuf 与 HTTP/1.1 + JSON 之间的鸿沟,不是靠改几个参数就能跨越的。想让前端直连 Go 后端的 gRPC 服务,必须加一层 gRPC-Web 网关来承担协议转换。这不是可选组件,而是必经通路。
可能有人会问,grpcwebproxy 不是也能用吗?但问题在于,它已经归档、不再维护了。本地跑个 demo 或许还能凑合,一上生产就容易露馅:没有 TLS 终止、没有健康检查、没有可观测性集成。Envoy 才是唯一靠谱的选择,尤其是在 Kubernetes 场景下。
实践中有几个关键点需要留意:
envoy.filters.http.grpc_web 必须显式启用,否则浏览器发 application/grpc-web+proto 请求时,会静默返回 415 Unsupported Media TypeOPTIONS)会直接失败。需要在 http_filters 里配置 envoy.filters.http.cors,或者交由后端处理docker-compose 部署,Envoy 容器要能访问 Go gRPC server 的 0.0.0.0:9090,不能绑 127.0.0.1——在容器网络里,localhost 指的是自己好消息是,业务代码完全不用动。但有两个隐性条件必须满足,否则网关转不动:
reflection.Register(server),否则前端调试工具(如 grpcurl 或 Web UI)查不到服务列表0.0.0.0:9090,不能是 127.0.0.1:9090;否则 Envoy 在另一容器里根本连不上w.Header().Set("Access-Control-Allow-Origin", "*"),且注意 Access-Control-Allow-Headers 至少包含 content-type 和 x-grpc-web生成的 JS 客户端桩(protoc-gen-grpc-web 输出)默认走 http://localhost:8080(grpcwebproxy 的默认端口),但你用的是 Envoy,所以需要手动指定网关地址:
host 参数:new MyServiceClient("http://your-envoy-host:10000")stream_idle_timeout,否则连接空闲 60s 后会自动断开,前端 onEnd 会收到 status.UNKNOWNfetch 手动拼请求——gRPC-Web 的协议头(如 Content-Type: application/grpc-web+proto)和帧格式(length-delimited)非常严格,手写极易出错最容易被忽略的一个点是:Envoy 的 grpc_web filter 只识别特定的 MIME 类型,而前端生成的 client 默认发的是 application/grpc-web+proto。如果后端 proto 编译时用了 --grpc-web_out=import_style=commonjs+dts,mode=grpcweb,但 Envoy 没配对这个类型,就会卡在 415。这个点不排查,其他配置都白搭。
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
8