Добавление заголовка CORS в пример по умолчанию gqlgen?

Я пытаюсь настроить базовый стек с помощью React, Apollo, обслуживаемый graphQL, обслуживаемый Go через gqlgen.

Я после началу работы руководства для gqlgen, который работает отлично.

Я также после началу работы руководства для Аполлона, который работает отлично.

Моя проблема заключается в том, что хром не позволяет мне пинговать серверную часть, когда я пытаюсь сшить их вместе. Я получаю сообщение об ошибке заголовка предварительной проверки CORS, что понятно, учитывая, что React включенlocalhost:3000 и сервер Go включен localhost:8080

gqlgen предоставил полезный пример того, как получить CORS, работающий на сервере Go здесь с помощью й и Go-CORS. Однако при условии, пример основан на Starwars примере gqlgen, а затем при получении стартером пример.

Я изменил пример CORS на следующее:

package main

import (
    "net/http"

    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/99designs/gqlgen/graphql/handler/transport"
    "github.com/99designs/gqlgen/graphql/playground"
    "github.com/FlockSupport/graphql/graph"
    "github.com/FlockSupport/graphql/graph/generated"
    "github.com/go-chi/chi"
    "github.com/gorilla/websocket"
    "github.com/rs/cors"
)

func main() {
    router := chi.NewRouter()

    // Add CORS middleware around every request
    // See https://github.com/rs/cors for full option listing
    router.Use(cors.New(cors.Options{
        AllowedOrigins:   []string{"http://localhost:8080"},
        AllowCredentials: true,
        Debug:            true,
    }).Handler)

    // srv := handler.New(starwars.NewExecutableSchema(starwars.NewResolver())) // MODIFIED THIS.
    srv := handler.New(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))

    srv.AddTransport(&transport.Websocket{
        Upgrader: websocket.Upgrader{
            CheckOrigin: func(r *http.Request) bool {
                // Check against your desired domains here
                return r.Host == "example.org"
            },
            ReadBufferSize:  1024,
            WriteBufferSize: 1024,
        },
    })

    router.Handle("/", playground.Handler("GraphQL Playground", "/query"))
    // router.Handle("/", handler.Playground("Starwars", "/query")) // MODIFIED THIS.
    router.Handle("/query", srv)

    err := http.ListenAndServe(":8080", router)
    if err != nil {
        panic(err)
    }
}

Сервер работает, но тестирование запросов через игровую площадку (localhost:8080, поэтому CORS здесь не имеет значения) дает следующую ошибку:

{
  "error": {
    "errors": [
      {
        "message": "transport not supported"
      }
    ],
    "data": null
  }
}

Это также не работает, даже если я настроил только маршрутизатор Chi:


func main() {
    router := chi.NewRouter()

    srv := handler.New(generated.NewExecutableSchema(generated.Config{Resolvers: &graph.Resolver{}}))

    router.Handle("/", playground.Handler("GraphQL Playground", "/query"))
    router.Handle("/query", srv)

    err := http.ListenAndServe(":8080", router)
    if err != nil {
        panic(err)
    }
}

Я получаю Server Cannot Be Reached когда я получаю доступ к localhost:8080 детская площадка.

Как правильно включить CORS на сервере gqlgen Go, чтобы React мог пинговать его?

3 ответа

Решение

У меня была такая же проблема, и я решил ее с помощью NewDefaultServer метод вместо New.

srv := handler.NewDefaultServer(.....)

Вам необходимо предоставить проверки CORS в качестве промежуточного программного обеспечения. Например, вы можете использовать github.com/rs/cors. Это может выглядеть как следующий код

mux.Handle("/playground", handler.Playground("API", "/gql"))
mux.Handle("/gql",
    handler.GraphQL(
        gen.NewExecutableSchema(gen.Config{Resolvers: resolver.New(dep)}),
        handler.ErrorPresenter(errorCustomize)))
h := cors.AllowAll().Handler(util.JwtMiddleware(mux))

srv := &http.Server{
    Addr:    ":8087",
    Handler: h,
}

У меня была такая же проблема, но на самом деле это было потому, что, когда я делал запрос на сервер, я не добавлял заголовок Content-Type: application/json. как ни странно мне пришлось включитьContent-Length заголовок при использовании почтальона.

Итак, когда я попробовал:

    curl --request POST \
    --url http://localhost:8000/ \
    --data '{"query":"query {\n  televisions {\n    id\n  }\n}"}'

Это был ответ:

{"errors":[{"message":"transport not supported"}],"data":null}

Но когда я добавил заголовок:

    curl --request POST \
    --url http://localhost:8000/ \
    --header 'content-type: application/json' \
    --data '{"query":"query {\n  televisions {\n    id\n  }\n}"}'

Ответ сервера обычно:

{"data":{"televisions":[]}}
Другие вопросы по тегам