React里调用gRPC接口为啥一直连不上后端?

迷人的庆晨 阅读 23

我用React写了个前端页面,想通过gRPC调用后端服务,但每次请求都失败,浏览器控制台报错说连接被拒绝。后端确认已经启动了gRPC服务,并且用其他客户端测试是通的。

我试过用@grpc/grpc-js在React里直接调用,但好像浏览器不支持原生gRPC?是不是得用gRPC-Web?下面是我现在写的代码:

import { GreeterClient } from './generated/helloworld_grpc_web_pb';
import { HelloRequest } from './generated/helloworld_pb';

const client = new GreeterClient('http://localhost:8080');
const request = new HelloRequest();
request.setName('world');

client.sayHello(request, {}, (err, response) => {
  if (err) console.error(err);
  else console.log(response.getMessage());
});

是不是哪里配置错了?还是说必须配合Envoy代理才能跑起来?

我来解答 赞 5 收藏
二维码
手机扫码查看
2 条解答
闲人彦森
浏览器确实不支持原生 gRPC,所以你得用 gRPC-Web。你已经在代码里用了 gRPC-web 的库,这没错。但是连接地址可能有问题,通常是 http 协议不够,你需要用 http2 或者通过代理。

代码给你,可以试试通过 Envoy 代理来转发请求:

1. 安装 Envoy。
2. 配置 Envoy,下面是个简单的配置文件示例 envoy.yaml:
static_resources:
listeners:
- name: listener_0
address:
socket_address:
address: 0.0.0.0
port_value: 9090
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
stat_prefix: ingress_http
route_config:
name: local_route
virtual_hosts:
- name: local_service
domains:
- "*"
routes:
- match:
prefix: "/"
route:
cluster: grpc_service
http_filters:
- name: envoy.filters.http.grpc_web
- name: envoy.filters.http.router
clusters:
- name: grpc_service
connect_timeout: 0.25s
type: logical_dns
lb_policy: round_robin
http2_protocol_options: {}
load_assignment:
cluster_name: grpc_service
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: localhost
port_value: 8080


3. 启动 Envoy:
envoy -c envoy.yaml


4. 修改你的前端代码连接地址为 Envoy 的监听地址:
const client = new GreeterClient('http://localhost:9090');
const request = new HelloRequest();
request.setName('world');

client.sayHello(request, {}, (err, response) => {
if (err) console.error(err);
else console.log(response.getMessage());
});


这样应该能解决连接被拒绝的问题。希望这能帮到你。
点赞
2026-03-24 19:23
 ___路喧
你遇到的问题主要是因为浏览器对 gRPC 原生支持有限,通常需要使用 gRPC-Web 来解决这个问题。你已经使用了 gRPC-Web 的库,但还需要确保一些配置正确。

首先,确认你的后端服务是否配置了正确的 CORS 设置,或者使用了一个反向代理(比如 Envoy 或 Nginx)来处理 gRPC-Web 请求。直接在浏览器里调 gRPC-Web 时,后端需要能够理解并处理这种特殊的请求格式。

其次,检查你的服务地址。gRPC-Web 通常使用 HTTP/2 over HTTP(即普通的 HTTP 协议),而不是 gRPC 默认的 HTTP/2。所以确保你的地址协议是 http://https://,而不是 grpc://grpcs://

最后,确保你的后端服务正确地配置了 gRPC-Web 插件或中间件,以便能够处理来自前端的 gRPC-Web 请求。

简单来说,你可能需要一个反向代理来桥接前端和后端之间的通信。这里有一个简单的 Nginx 配置示例,帮助你快速搭建一个:

pre class="pure-highlightjs line-numbers">server {
listen 8080;

location / {
grpc_pass grpc://localhost:50051;
}

location /your-grpc-service-path/ {
grpc_web_enable on;
grpc_set_header Content-Type application/grpc-web+proto;
grpc_pass grpc://localhost:50051;
}
}


这个配置假设你的 gRPC 后端运行在 localhost:50051 上。你需要根据实际情况调整监听端口和 grpc_pass 的地址。

另外,确保你的 React 应用里的请求路径和后端提供的服务路径匹配。

希望这些信息能帮到你,调试这些问题有时候确实挺烦人的。
点赞
2026-03-21 08:20