Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Access-Control-Expose-Headers errors in browser when response from server #396

Open
scippio opened this issue Apr 22, 2019 · 10 comments
Open

Comments

@scippio
Copy link

scippio commented Apr 22, 2019

Hi,

I'm playing with grpc-web and maybe I'm doing something wrong, but I'm geting this:
image

I'm sucessfully recieved request on server with all data... but response end with this errors in browser (Chrome) :(

My test code:

I create good request from my js client:

import { RegistrationServicePromiseClient, RegistrationServiceClient, Data } from '~/api/registration_grpc_web_pb.js'

...

var data = new Data()
data.setEmail("test@example.com")
data.setPassword("abcd")
var client = new RegistrationServiceClient("https://localhost:8000")
client.newRegistration(data,null,(res) => {
    console.log("res:",res)
})

and on my golang server (in main func):

func main() {
	creds, err := credentials.NewServerTLSFromFile("localhost.pem", "localhost-key.pem")
	if err != nil {
		fmt.Print(err)
	}

	grpcServer := grpc.NewServer(grpc.Creds(creds))
	wrappedGrpc := grpcweb.WrapServer(grpcServer, grpcweb.WithAllowedRequestHeaders([]string{"*"}), grpcweb.WithWebsockets(false))

	srv := TestService{}
	protos.RegisterRegistrationServiceServer(grpcServer, &srv)

	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Access-Control-Allow-Origin", "*")
		w.Header().Set("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE")
		w.Header().Set("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization, x-user-agent, x-grpc-web, grpc-status, grpc-message")
		w.Header().Set("Access-Control-Expose-Headers", "grpc-status, grpc-message")
		if r.Method == "OPTIONS" {
			return
		}

		if wrappedGrpc.IsGrpcWebRequest(r) {
			wrappedGrpc.ServeHTTP(w, r)
		} else {
			// Fall back to other servers.
			http.DefaultServeMux.ServeHTTP(w, r)
		}
	})

	httpserver := http.Server{
		Addr:           ":8000",
		Handler:        handler,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	http2.ConfigureServer(&httpserver, nil)

	err = httpserver.ListenAndServeTLS("localhost.pem", "localhost-key.pem")
	if err != nil {
		panic(err)
	}
}
func (ser *TestService) NewRegistration(ctx context.Context, data *protos.Data) (*protos.Response, error) {

	fmt.Printf("RECIEVED: %v\n", data)

	res := protos.Response{}
	res.Status = 123
	res.Message = "Test"

	return &res, nil
}

Verion grpc-web: 0.9.1

thanks for any help...

@johanbrandhorst
Copy link
Contributor

What does the response from the server look like in the browser? Could you show the output of the network tab in your browser debug tools?

@johanbrandhorst
Copy link
Contributor

You shouldn't have to call http2.ConfigureServer by the way, it will support http/2 automatically.

@scippio
Copy link
Author

scippio commented Apr 22, 2019

image

image

@johanbrandhorst
Copy link
Contributor

What does the chrome console warning drop down say? I noticed you're serving the UI on HTTP but the grpcwebproxy on HTTPS, it's not a security mismatch?

@scippio
Copy link
Author

scippio commented Apr 22, 2019

I don't think so... but good point I'll try unify this...
image

EDIT: I tried only http and https too everywhere and it's still same...

@jonnyreeves
Copy link
Contributor

jonnyreeves commented Apr 23, 2019 via email

@scippio
Copy link
Author

scippio commented Apr 23, 2019

You can see the OPTIONS request and my server source for pre-flight setup... I don't using any proxy. Only this client and server code.

@scippio
Copy link
Author

scippio commented Apr 23, 2019

🤔 When I set this headers manually on server after other headers:

w.Header().Set("grpc-status", "123")
w.Header().Set("grpc-message", "true")

it's recieved ok:
image
(.. and I don't know why callback is fired five times...)

@scippio
Copy link
Author

scippio commented Apr 23, 2019

Ok, I change my client code from "rpcCall" to "unaryCall" (promise version) (functions in generated js files from proto):

So I change exactly this lines:

// var client = new RegistrationServiceClient("https://localhost:8000")
var client = new RegistrationServicePromiseClient("https://localhost:8000")

// client.newRegistration(data,meta,(res) => {
//     console.log("res:",res)
// })

client.newRegistration(data,meta).then((res) => {
     console.log("res:",res)
     console.log("res:",res.toObject())
}).catch((err) => {
     console.log("err: ",err)
})

and it works! But I have still same error messages 😢
image

@scippio
Copy link
Author

scippio commented Apr 29, 2019

I think a found the same problem in the past: grpc/grpc-web#518

EDIT: So I think I will try use Envoy...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants