I'm currently working on a project where I have a C++ gRPC server and a ReactJS client. The problem is I can't get the client to communicate with the server due to CORS restritions. Everytime I try to call my server from my client (in firefox) I get this error: Http response at 400 or 500 level, http status code: 0, with this reason: Reason: CORS header 'Access-Control-Allow-Origin' missing MDN docs
So far, I have a simple proto file (same on both sides) with one service being the greeter service:
pricing.proto:
syntax = "proto3";
// The greeter service definition.
service GrpcPricer {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
I have my c++ server running locally:
#include <iostream>
#include <string>
#include <fstream>
#include <grpcpp/ext/proto_server_reflection_plugin.h>
#include <grpcpp/grpcpp.h>
#include <grpcpp/health_check_service_interface.h>
#include "pricing.grpc.pb.h"
#include "pricing.pb.h"
using grpc::Server;
using grpc::ServerBuilder;
using grpc::ServerContext;
using grpc::Status;
class GrpcPricerServiceImpl final : public GrpcPricer::Service
{
public:
Status SayHello(ServerContext *context, const HelloRequest *request,
HelloReply *reply) override
{
context->AddInitialMetadata("access-control-allow-origin", "*"); // <- I added this line to try to resolve the CORS restriction error
std::cout << "Hello " << request->name() << std::endl;
std::string prefix("Hello ");
reply->set_message(prefix + request->name());
return Status::OK;
}
};
void RunServer()
{
std::string server_address("0.0.0.0:50051");
GrpcPricerServiceImpl service;
grpc::EnableDefaultHealthCheckService(true);
grpc::reflection::InitProtoReflectionServerBuilderPlugin();
ServerBuilder builder;
// Listen on the given address without any authentication mechanism.
builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
// Register "service" as the instance through which we'll communicate with
// clients. In this case it corresponds to a *synchronous* service.
builder.RegisterService(&service);
// Finally assemble the server.
std::unique_ptr<Server> server(builder.BuildAndStart());
std::cout << "Server listening on " << server_address << std::endl;
// Wait for the server to shutdown. Note that some other thread must be
// responsible for shutting down the server for this call to ever return.
server->Wait();
}
int main(int argc, char **argv)
{
RunServer();
return 0;
}
And my ReactJS client with a simple call to the greeter service on a button click:
const { HelloRequest, HelloReply } = require('../pricing_pb.js');
const { GrpcPricerClient } = require('../pricing_grpc_web_pb.js');
const client = new GrpcPricerClient('http://localhost:50051');
const request = new HelloRequest();
// This is the function being called
const callGrpcService = () => {
client.sayHello(request, {}, (err, response) => {
if (err) {
console.error(err.message);
} else {
console.log(response.getMessage());
}
});
What I've tried is to see if my server was responding and so I use this tool grpcurl. When I use this tool, I can get an answer from the server. Here's the command:
grpcurl -d '{"name": "World"}' -plaintext localhost:50051 GrpcPricer/SayHello
Which gives me the following response:
{
"message": "Hello World"
}
So I reckon the problem comes from the client side. So I also tried to add some headers/metadata to my request with no success. I also tried the firefox add-on CORS everywhere to get rid of the error but it's not a viable solution and does not seem to work great.
Any Ideas welcomed, thanks