Ошибка CORS даже после установки заголовков Access-Control-Allow-Origin или других Access-Control-Allow- * на стороне клиента.

У меня есть приложение Vue, созданное с опцией webpack-simple. Я пытаюсь сделать GET запрос к https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en, но получаю сообщение об ошибке:

XMLHttpRequest не может загрузить https://api.forismatic.com/api/1.0/?method=getQuote&format=json&lang=en. Ответ на предполетный запрос не проходит проверку контроля доступа: на запрошенном ресурсе отсутствует заголовок Access-Control-Allow-Origin. Следовательно, к источнику "http://127.0.0.1:8080" доступ не разрешен.

Я использую vue-resource и добавил:

Vue.http.headers.common['Access-Control-Allow-Origin'] = '*'

Это не имеет никакого эффекта.

Я также добавил это в параметр devServer в webpack.config.js:

devServer: {
  historyApiFallback: true,
  noInfo: true,
  headers: {
    "Access-Control-Allow-Origin": "*"
  }
}

Это тоже не решает проблемы; сообщение об ошибке остается прежним.

Как решить эту проблему?


person wrahim    schedule 28.05.2017    source источник


Ответы (1)


Access-Control-Allow-Origin - это заголовок ответа, который должен отправить сервер, на который идет запрос.

А все остальные Access-Control-Allow-* заголовки - это заголовки ответов для отправки серверами.

Если вы не контролируете сервер, на который отправляется ваш запрос, а проблема с ответом от этого сервера заключается в отсутствии заголовка Access-Control-Allow-Origin или других заголовков Access-Control-Allow-*, вы все равно можете заставить все работать - отправив запрос через CORS прокси.

Вы можете легко запустить свой собственный прокси, используя код из https://github.com/Rob--W/cors-anywhere/.
Вы также можете легко развернуть собственный прокси на Heroku всего за 2-3 минуты с помощью 5 команд:

git clone https://github.com/Rob--W/cors-anywhere.git
cd cors-anywhere/
npm install
heroku create
git push heroku master

После выполнения этих команд у вас будет работать собственный сервер CORS Anywhere, например, https://cryptic-headland-94862.herokuapp.com/.

Теперь добавьте к URL-адресу вашего запроса префикс URL-адреса вашего прокси:

https://cryptic-headland-94862.herokuapp.com/https://example.com

Добавление URL-адреса прокси в качестве префикса приводит к тому, что запрос выполняется через ваш прокси, который затем:

  1. Перенаправляет запрос на https://example.com.
  2. Получает ответ от https://example.com.
  3. Добавляет заголовок Access-Control-Allow-Origin к ответу.
  4. Передает этот ответ с добавленным заголовком обратно запрашивающему коду внешнего интерфейса.

Затем браузер позволяет коду внешнего интерфейса получить доступ к ответу, потому что этот ответ с заголовком ответа Access-Control-Allow-Origin - это то, что браузер видит.

Это работает, даже если запрос запускает браузеры для выполнения запроса OPTIONS предварительной проверки CORS, потому что в этом случае прокси также отправляет обратно заголовки Access-Control-Allow-Headers и Access-Control-Allow-Methods, необходимые для успешной предварительной проверки.

И если у вас есть код внешнего интерфейса, который добавляет заголовок Access-Control-Allow-Origin или другие заголовки Access-Control-Allow-* к запросу на стороне клиента, удалите этот код - потому что единственный эффект, который вы производите, добавляя эти заголовки запроса, заключается в том, что вы запускаете свой браузер для отправки OPTIONS запрос CORS, а не фактический GET или POST запрос в вашем коде.

person sideshowbarker    schedule 28.05.2017
comment
Я хотел бы отметить, что cors-anywhere.herokuapp.com - достойное временное решение, но не то, которое вы захотите использовать в производственной среде, поскольку оно может включать передачу конфиденциальных данных через чужое приложение. - person ceejayoz; 29.05.2017
comment
@ceejayoz Верно, но в этом случае запрос представляет собой простой запрос GET без учетных данных, который, как представляется, является общедоступной службой, которая отправляет назад случайные кавычки. Так что в данном случае прокси - это просто способ обойти тот факт, что поставщики этой услуги не утруждают себя добавлением заголовка ответа Access-Control-Allow-Origin в сами ответы. Кажется, нет веских причин, по которым они не могли быть ... - person sideshowbarker; 29.05.2017