Graphql-go: CORS error

Created on 24 Mar 2017  路  4Comments  路  Source: graph-gophers/graphql-go

Hi there,

I am learning graphql and relay. here is an error that I came across:

Fetch API cannot load http://localhost:8080/graphql. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 400. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Any suggestion would be very appreciated.

Here is the main go function:
func main() {
http.Handle("/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write(page)
}))

http.Handle("/graphql", &relay.Handler{Schema: schema})

log.Fatal(http.ListenAndServe(":8080", nil))

}

Most helpful comment

If you want to allow people to request your graphql api from another domain (from a browser) then you'll need to add the Access-Control-Allow-Origin header to your graphql handler.

One way you could do this is with a "middleware" approach.

func CorsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // allow cross domain AJAX requests
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
        next.ServeHTTP(w,r)
    })
}

so that you could wrap your relay.Handler with this middleware:

http.Handle("/graphql", CorsMiddleware(&relay.Handler{Schema: schema}))

Please be aware that allowing Cross-Origin requests to your api could be a security vulnerability.

All 4 comments

If you want to allow people to request your graphql api from another domain (from a browser) then you'll need to add the Access-Control-Allow-Origin header to your graphql handler.

One way you could do this is with a "middleware" approach.

func CorsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // allow cross domain AJAX requests
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
        next.ServeHTTP(w,r)
    })
}

so that you could wrap your relay.Handler with this middleware:

http.Handle("/graphql", CorsMiddleware(&relay.Handler{Schema: schema}))

Please be aware that allowing Cross-Origin requests to your api could be a security vulnerability.

https://en.wikipedia.org/wiki/Cross-origin_resource_sharing serves as a good reference on the topic of CORS.

Thank you so much. Please close this issue.

if you are using apollo-boost in a react app, your browser might do a CORS preflight request, which is an OPTIONS request. the relay handler does not handle that properly, so I extended the CorsMiddleware function from https://github.com/graph-gophers/graphql-go/issues/74#issuecomment-289098639
to also respond to the preflight request:

func CorsMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        w.Header().Set("Access-Control-Allow-Origin", "*")
        w.Header().Set("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept")
        w.Header().Set("Access-Control-Allow-Methods", "GET, POST,OPTIONS")
        if r.Method == "OPTIONS" {
            w.WriteHeader(http.StatusOK)
            return
        }
        next.ServeHTTP(w, r)
    })
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

vladimiroff picture vladimiroff  路  6Comments

JitinGuglani picture JitinGuglani  路  6Comments

linuxmonk picture linuxmonk  路  3Comments

Hagbarth picture Hagbarth  路  6Comments

rogchap picture rogchap  路  5Comments