无法从 Angular 客户端调用 gRPC 服务
Unable to call gRPC service from Angular client
我正在尝试从 Angular 应用程序调用 gRPC 服务。
如果我在本地托管服务器并从 Anuglar 应用程序调用它,那么它就可以工作。
const client = new HelloWorldServiceClient("http://localhost:5001");
const request = new SayHelloMessage();
request.setName("User");
client.sayHelloWorld(request, (err: any, response: any) => {
if (err) {
console.log(err);
this.response = err;
return;
}
this.response = response.getMessage();
});
但是,当我尝试调用托管在远程服务器上的 gRPC 服务时,它抛出“没有 headers 的情况下关闭响应”错误。
更改代码:
const client = new HelloWorldServiceClient("http://server_name:5001");
如果我尝试使用 NodeJS 客户端调用托管在服务器上的相同服务,那么它也能正常工作。
NodeJS 代码:
var url = "server_name_with_out_http:5001"; // e.g. server_name:5001 and not http://server_name:5001
const client = new HelloWorldServiceClient(
url,
grpc.credentials.createInsecure()
);
var req = { name: "User" };
client.sayHelloWorld(req, (error, reply) => {
if (!error) {
console.log(reply.message);
} else {
console.log(error);
}
});
Angular 应用程序无法调用服务器上托管的 gRPC 服务的原因可能是什么?
Chrome 开发工具日志:
这很可能是由常见问题引起的 CORS Browser restrictions, and not exactly by angular. This question 包含关于 CORS 的重要指导。
从 Node 应用程序(或邮递员)调用 HTTP 服务不会强制执行 CORS,而从市场标准浏览器调用它肯定会。
我知道它比我的下一个简化评论要多得多,但这应该给你一个起点(更深入的探讨在我上面分享的链接中)
对于浏览器执行XMLHttpRequest's从一个网站到其他域(或同一域的其他端口):
- 浏览器将在每次向其他域发出真实请求之前发送一个 OPTIONS HTTP 请求,并且仅当 OPTIONS 响应 headers 授权时才允许实际请求。
- “其他”网站必须配置为使用特定 Headers(
Access-Control-Allow-Origin
、Access-Control-Request-*
...)回复 OPTIONS 请求。
==> 如果其他服务器未回复 OPTIONS 请求或未在 OPTIONS 响应中提供适当的 headers,您会得到一系列不同的错误,并且“Response closed without headers" 就是其中之一。
我认为您的 gRPC Web 应用程序没有配置正确的 CORS 来授权来自您托管 angular 应用程序的网站的通信(即使它是本地主机,您仍然需要配置它) .
This article 有关于如何在 .netcore 应用程序上配置 CORS 的实用指南
最后,This github issue / responses 包含一些关于一些人在使用 gRPC 时遇到的类似错误的更多信息,您可能遇到过相同的错误。如果您已经配置了 CORS 规则。
我建议不要直接从您的浏览器客户端调用您的后端(如果您不想这样做,请告诉我)并改用反向代理。有很多工具可以做到这一点:
事实上,gRPC 的 Github 存储库中的示例使用了 envoy(grpc-io 邮件列表中的 check here) and one of the mail 提到不建议直接将后端与 gRPC 网络前端联系。
我正在尝试从 Angular 应用程序调用 gRPC 服务。
如果我在本地托管服务器并从 Anuglar 应用程序调用它,那么它就可以工作。
const client = new HelloWorldServiceClient("http://localhost:5001");
const request = new SayHelloMessage();
request.setName("User");
client.sayHelloWorld(request, (err: any, response: any) => {
if (err) {
console.log(err);
this.response = err;
return;
}
this.response = response.getMessage();
});
但是,当我尝试调用托管在远程服务器上的 gRPC 服务时,它抛出“没有 headers 的情况下关闭响应”错误。
更改代码:
const client = new HelloWorldServiceClient("http://server_name:5001");
如果我尝试使用 NodeJS 客户端调用托管在服务器上的相同服务,那么它也能正常工作。
NodeJS 代码:
var url = "server_name_with_out_http:5001"; // e.g. server_name:5001 and not http://server_name:5001
const client = new HelloWorldServiceClient(
url,
grpc.credentials.createInsecure()
);
var req = { name: "User" };
client.sayHelloWorld(req, (error, reply) => {
if (!error) {
console.log(reply.message);
} else {
console.log(error);
}
});
Angular 应用程序无法调用服务器上托管的 gRPC 服务的原因可能是什么?
Chrome 开发工具日志:
这很可能是由常见问题引起的 CORS Browser restrictions, and not exactly by angular. This question 包含关于 CORS 的重要指导。
从 Node 应用程序(或邮递员)调用 HTTP 服务不会强制执行 CORS,而从市场标准浏览器调用它肯定会。
我知道它比我的下一个简化评论要多得多,但这应该给你一个起点(更深入的探讨在我上面分享的链接中)
对于浏览器执行XMLHttpRequest's从一个网站到其他域(或同一域的其他端口):
- 浏览器将在每次向其他域发出真实请求之前发送一个 OPTIONS HTTP 请求,并且仅当 OPTIONS 响应 headers 授权时才允许实际请求。
- “其他”网站必须配置为使用特定 Headers(
Access-Control-Allow-Origin
、Access-Control-Request-*
...)回复 OPTIONS 请求。
==> 如果其他服务器未回复 OPTIONS 请求或未在 OPTIONS 响应中提供适当的 headers,您会得到一系列不同的错误,并且“Response closed without headers" 就是其中之一。
我认为您的 gRPC Web 应用程序没有配置正确的 CORS 来授权来自您托管 angular 应用程序的网站的通信(即使它是本地主机,您仍然需要配置它) .
This article 有关于如何在 .netcore 应用程序上配置 CORS 的实用指南
最后,This github issue / responses 包含一些关于一些人在使用 gRPC 时遇到的类似错误的更多信息,您可能遇到过相同的错误。如果您已经配置了 CORS 规则。
我建议不要直接从您的浏览器客户端调用您的后端(如果您不想这样做,请告诉我)并改用反向代理。有很多工具可以做到这一点:
事实上,gRPC 的 Github 存储库中的示例使用了 envoy(grpc-io 邮件列表中的 check here) and one of the mail 提到不建议直接将后端与 gRPC 网络前端联系。