You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native中grpc-web无法连接AWS上的Envoy代理服务器

React Native iOS模拟器中gRPC-Web调用AWS Elastic Beanstalk Envoy代理失败的排查与解决

问题背景

部署在AWS Elastic Beanstalk的测试用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: 80 }
      filter_chains:
        - filters:
            - name: envoy.filters.network.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: grpc_cluster
                            timeout: 0s
                            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,accept,user-agent,cache-control,content-type,content-transfer-encoding,custom-header-1,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
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
                  - name: envoy.filters.http.cors
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
                  - name: envoy.filters.http.router
                    typed_config:
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
  clusters:
    - name: grpc_cluster
      connect_timeout: 0.25s
      type: logical_dns
      http2_protocol_options: {}
      lb_policy: round_robin
      load_assignment:
        cluster_name: grpc_cluster
        endpoints:
          - lb_endpoints:
              - endpoint:
                  address:
                    socket_address:
                      address: ${server_url}
                      port_value: ${server_port}

使用grpcurl或Node.js客户端(测试代码如下)调用正常:

import { LightStreamerClient } from "../protos-dist/LightstreamerServiceClientPb";
import { Empty, ServerInfo } from "../protos-dist/lightstreamer_pb";
import { RpcError } from "grpc-web";

const XMLHttpRequest = require("xhr2");

const client = new LightStreamerClient("http://mytest.us-west-1.elasticbeanstalk.com");

globalThis.XMLHttpRequest = XMLHttpRequest;

function getServerInfo(): Promise<[RpcError, ServerInfo]> {
  return new Promise((res) => {
    client.getServerInfo(new Empty(), null, (_err, response) => {
      res([_err, response]);
    });
  });
}

async function main() {
  console.log("Testing envoy server...");
  const [err, response] = await getServerInfo();
  console.log({ err, response });
  console.log("Done.");
}

main();

但在React Native iOS模拟器中执行相同gRPC-Web调用时失败,报错:[RpcError: Http response at 400 or 500 level, http status code: 0]。本地运行相同Envoy配置时所有测试正常,怀疑问题与CORS相关。

排查与解决办法

1. 调整Envoy过滤器顺序(核心修复)

当前配置中grpc_web过滤器排在cors过滤器之前,会导致CORS预检OPTIONS请求先被gRPC-Web过滤器处理——而gRPC-Web不支持OPTIONS方法,直接返回错误。需将cors过滤器移至最前面,确保OPTIONS请求优先被CORS规则处理:

http_filters:
  - name: envoy.filters.http.cors
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
  - name: envoy.filters.http.grpc_web
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_web.v3.GrpcWeb
  - name: envoy.filters.http.router
    typed_config:
      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router

2. 检查React Native iOS的ATS配置

iOS默认阻止HTTP请求,需在项目Info.plist中添加ATS例外,允许访问EB域名:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSExceptionDomains</key>
  <dict>
    <key>mytest.us-west-1.elasticbeanstalk.com</key>
    <dict>
      <key>NSIncludesSubdomains</key>
      <true/>
      <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
      <true/>
    </dict>
  </dict>
</dict>

3. 验证AWS EB网络配置

  • 确认EB实例安全组开放80端口,允许iOS模拟器所在网络的流量访问
  • 检查EB是否有负载均衡器或WAF规则拦截OPTIONS请求或gRPC-Web请求头

4. 查看Envoy访问日志定位问题

登录EB实例,查看/tmp/admin_access.log,确认请求是否到达Envoy、请求方法/头信息、返回状态码,进一步定位问题环节。

内容的提问来源于stack exchange,提问作者jowparks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 14:23:11