Запрос Axios, получающий ошибку CORS, только когда внутри функции обратного вызова / асинхронности - PullRequest
1 голос
/ 01 апреля 2019

Я использую VueJS для приложения, которое создаю.Сервер, который у меня есть, написан на Голанге и настроен на прием CORS.В приложении, в одном из моих компонентов, searchBar, я настроил его на выборку некоторых данных перед его созданием.

var searchBar = {
    prop: [...],
    data: function() {
        return { ... };
    },
    beforeCreate: function() {
        var searchBar = this;

        axios.request({
            url: '/graphql',
            method: 'post',
            data: {
                'query': '{courses{id, name}}'
            }
        })
        .then(function(response) {
            searchBar.courses = response.data.data.courses;
        });
    },
    methods: { ... },
    template: `...`
};

Axios отлично работает здесь.Он получает данные, которые мне нужны.searchBar имеет кнопку, которая заставляет его генерировать событие, которое затем захватывается другим компонентом, searchResults.После получения события searchResults извлечет некоторые данные.

var searchResults = {
    data: function() {
        return { ... }
    },
    mounted: function() {
        var sr = this;

        this.$bus.$on('poll-server', function(payload) {
            var requestData = {
                url: '/graphql',
                method: 'post',
                data: { ... },
                ...
            };
            ...

            axios.request(requestData)
                 .then(function(response) {
                     console.log(response);
                 }
            );
        });
    },
    template: `...`
};

Обратите внимание, что мой запрос запроса Axios теперь находится внутри функции обратного вызова.Когда этот вызов выполнен, я получаю сообщение об ошибке CORS:

Доступ к XMLHttpRequest в 'http://127.0.0.1:9000/graphql' из источника' http://127.0.0.1:8080' заблокирован политикой CORS: Ответ напредварительный запрос не проходит проверку контроля доступа: в запрашиваемом ресурсе отсутствует заголовок «Access-Control-Allow-Origin».

Мой сервер расположен по адресу http://127.0.0.1:9000, а клиент находится вhttp://127.0.0.1:8080.Вот содержание OPTIONS запроса второго вызова запроса.

Second call's OPTIONS method request headers.

Для сравнения приведен заголовок запроса первого вызова запроса(это работает!).

First call's OPTIONS method request headers.

Я уже настроил свой сервер Golang для поддержки CORS через go-chi/cors.Вот как это настроить.

router := chi.NewRouter()
...    
// Enable CORS.
cors := cors.New(cors.Options{
    AllowedOrigins:   []string{"*"},
    AllowedMethods:   []string{"POST", "OPTIONS"},
    AllowedHeaders:   []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token"},
    ExposedHeaders:   []string{"Link"},
    AllowCredentials: true,
    MaxAge:           300,
})

router.Use(
    render.SetContentType(render.ContentTypeJSON),
    middleware.Logger,
    middleware.DefaultCompress,
    middleware.StripSlashes,
    middleware.Recoverer,
    cors.Handler,
)

router.Post("/graphql", gqlServer.GraphQL())

return router, db

Что вызывает у меня ошибку и как ее можно решить?

Ответы [ 3 ]

2 голосов
/ 01 апреля 2019

Я все еще подозреваю настройку go-chi CORS.Я бы посоветовал посмотреть на настройку CORS вручную.Это не так сложно.Эта страница получит базовую настройку: https://flaviocopes.com/golang-enable-cors/

Если это работает с вашими вложенными настройками API, мы можем затем вернуться к решению проблемы конфигурации go-chi.


Обновление:

Я бы также рассмотрел другие этапы промежуточного программного обеспечения - закомментировал все несущественные.

Обработчики промежуточного программного обеспечения обычно проверяют r *http.Request или записывают заголовки в w http.ResponseWriter и тогда конечный обработчик напишет в ответ body .Но во всей цепочке промежуточного программного обеспечения следующий поток записи заголовка / тела должен выглядеть как один из этих двух потоков:

Success:

w.Header().Set(...) // headers
w.Write(...) // body

Обратите внимание, что вышеприведенный поток вызоветнеявная запись кода состояния http, чтобы заголовки отображались первый и тело второй :

w.Header().Set(...) // headers
w.WriteHeader(http.StatusOK) // implicit success http status code
w.Write(...) // body

Сбой:

В случае сообщения об ошибке во время выполнения поток должен быть:

w.Header().Set(...) // headers
w.WriteHeader(http.StatusInternalServerError) // some unrecoverable error 
w.Write(...) // optional body

Причина, по которой я поднял этот вопрос, я видел 3 типа ошибок, которые портят этот поток:

  • плохие обработчики промежуточного программного обеспечения записывают заголовки после тела, вызывая замешательство клиента
  • , вызывая http.Error, думая, что останавливает API-интерфейс мертвым - вместо немедленного возврата после http.Error и гарантируя, что последующие обработчики промежуточного программного обеспечения не будут вызваны
  • дважды напишите один и тот же заголовокПерезапись заголовков в последующем обработчике приведет к тому, что клиент увидит последнюю версию (таким образом перекрывая все предыдущие версии)

Таким образом, чтобы полностью отследить вещи, я бы log.Println записал все заголовки / тела для вашего APIчтобы убедиться, что вышеуказанный поток корректен и никакие предполагаемые значения не перезаписываются.

2 голосов
/ 01 апреля 2019

Ожидается ошибка CORS.Плагин CORS, который вы используете, выполняет фильтрацию запросов для вас.Если вы посмотрите список разрешенных заголовков, то увидите, что в нем отсутствует заголовок с именем snb-user-gps-location, который вы пытаетесь отправить в своем вызове axios.

Либо добавьте этот заголовок в список разрешенных, либо неотправить его из внешнего интерфейса.

0 голосов
/ 01 апреля 2019

Вам не хватает только Access-Control-Allow-Origin .Это заголовок ответа, сообщающий вашему браузеру, что cors разрешен для этого домена.Проверьте, есть ли проблема с вашей конфигурацией Cors.Возможно, проблема с конфигурацией?Может быть, вам нужно разрешить это для 120.0.0.1:8080.

...