Flutter gRPC请求抛出“潜在CORS问题”错误求助排查
Flutter gRPC请求CORS错误排查求助
发起gRPC请求时遇到以下错误:gRPC Error (code: 2, codeName: UNKNOWN, message: HTTP request completed without a status (potential CORS issue)
采用gRPC实现客户端与服务端通信,测试Ping-Pong示例时出现该CORS错误,已配置Envoy但问题依旧,以下是相关代码与配置:
PingPong服务函数(Go)
package products import ( "context" pb "github.com/yohanderson/cidtmi/api/pingpong" // protoc generated package ) type Server struct { pb.UnimplementedPingPongServiceServer } func (s *Server) Ping(ctx context.Context, in *pb.EmptyMessage) (*pb.Pong, error) { return &pb.Pong{Message: "Pong"}, nil }
Go服务端代码
func main() { dbinfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable", "localhost", 8000, "postgres", "xxxxxx", "database") db, err := sql.Open("postgres", dbinfo) if err != nil { log.Fatalf("failed to open database: %v", err) } defer db.Close() path := "0.0.0.0:8081" lis, err := net.Listen("tcp", path) if err != nil { log.Fatalf("failed to listen: %v", err) } log.Println("Server is listening on #{path}") s := grpc.NewServer() pingSrv := &pingPong.Server{} apiPingPong.RegisterPingPongServiceServer(s, pingSrv) appSrv := &serviceAppointments.Server{DB: db} apiAppointments.RegisterAppointmentsServer(s, appSrv) prodSrv := &serviceProducts.Server{DB: db} apiProducts.RegisterProductsServer(s, prodSrv) if err := s.Serve(lis); err != nil { log.Fatalf("failed to serve: %v", err) } }
Envoy配置文件
admin: access_log_path: /tmp/admin_access.log address: socket_address: { address: 0.0.0.0, port_value: 9901 } static_resources: listeners: - name: listener_0 address: socket_address: { address: 0.0.0.0, port_value: 8080 } filter_chains: - filters: - name: envoy.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager codec_type: auto stat_prefix: ingress_http route_config: name: local_route virtual_hosts: - name: local_service domains: ["*"] routes: - match: { prefix: "/" } route: cluster: greeter_service max_stream_duration: grpc_timeout_header_max: 0s cors: allow_origin_string_match: - prefix: "*" allow_methods: GET, PUT, DELETE, POST, OPTIONS allow_headers: keep-alive,user-agent,cache-control,content-type,content-transfer-encoding,x-accept-content-transfer-encoding,x-accept-response-streaming,x-user-agent,x-grpc-web,grpc-timeout max_age: "1728000" expose_headers: custom-header-1,grpc-status,grpc-message http_filters: - name: envoy.filters.http.grpc_web - name: envoy.filters.http.cors - name: envoy.filters.http.router clusters: - name: greeter_service connect_timeout: 0.25s type: logical_dns http2_protocol_options: {} lb_policy: round_robin load_assignment: cluster_name: cluster_0 endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 0.0.0.0 port_value: 8081
Flutter前端代码
class GrpcService { PingPongServiceClient? pingPongClient; void init() { final channel = GrpcWebClientChannel.xhr(Uri.parse('http://192.168.1.110:8080')); pingPongClient = PingPongServiceClient(channel); } Future<Pong> ping() async { final emptyMessage = EmptyMessage(); final response = await pingPongClient!.ping(emptyMessage); return response; } }
按钮触发逻辑
ElevatedButton(onPressed: () async { final response = await grpcService.ping(); print('Received: ${response.message}'); }, child: Text('verificar')),
完整错误栈
Error: gRPC Error (code: 2, codeName: UNKNOWN, message: HTTP request completed without a status (potential CORS issue), details: null, rawResponse: , trailers: {}) dart-sdk/lib/_internal/js_dev_runtime/private/ddc_runtime/errors.dart 327:10 createErrorWithStack dart-sdk/lib/_internal/js_dev_runtime/patch/core_patch.dart 337:28 _throw dart-sdk/lib/core/errors.dart 120:5 throwWithStackTrace dart-sdk/lib/async/zone.dart 1386:11 callback dart-sdk/lib/async/schedule_microtask.dart 40:11 _microtaskLoop dart-sdk/lib/async/schedule_microtask.dart 49:5 _startMicrotaskLoop dart-sdk/lib/_internal/js_dev_runtime/patch/async_patch.dart 181:15 <fn>
排查与解决方法
调整Envoy过滤器顺序
当前配置中grpc_web过滤器在cors之前,导致CORS校验无法优先处理预检请求。修改http_filters顺序为:http_filters: - name: envoy.filters.http.cors - name: envoy.filters.http.grpc_web - name: envoy.filters.http.router修复Envoy集群配置错误
clusters下的cluster_name与集群名称greeter_service不匹配,修改为:load_assignment: cluster_name: greeter_service endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 0.0.0.0 port_value: 8081修正Go服务端日志语法
Go中字符串格式化需用%s而非#{path},修改日志行:log.Printf("Server is listening on %s", path)确保服务正确监听8081端口。
优化CORS配置(开发环境)
若为开发阶段,可将allow_origin_string_match替换为更直接的配置:cors: allow_origins: ["*"] allow_methods: GET, PUT, DELETE, POST, OPTIONS allow_headers: keep-alive,user-agent,cache-control,content-type,x-grpc-web,grpc-timeout max_age: "1728000" expose_headers: grpc-status,grpc-message验证网络连通性
确认Flutter设备能访问192.168.1.110:8080,可通过浏览器打开该地址测试Envoy是否正常响应。
内容的提问来源于stack exchange,提问作者Levy Márquez
相关产品推荐
相关产品推荐

