Ответ на предполетный запрос не проходит ошибку проверки доступа

Точная ошибка, с которой я борюсь: "Ответ на предпечатный запрос не проходит проверку контроля доступа: в запрошенном ресурсе отсутствует заголовок" Access-Control-Allow-Origin ". Следовательно, исходному" null "запрещен доступ. ".

Я пытаюсь получить данные JSON, используя JavaScript с https://api.kraken.com/0/public/OHLC?pair=ETHEUR. Для этого я создал объект XMLHttpRequest и указал GET в качестве типа запроса. Предположительно, это простой запрос, однако ошибка говорит о том, что предварительный запрос был отправлен. В чем причина такого поведения? При этом, чтобы исправить эту ошибку, я попытался установить заголовок запроса, в котором я указал '*' в качестве значения для Access-Control-Allow-Origin, но я все еще получаю ошибку. Я просмотрел ответы на те же вопросы, что и мои, но не смог выяснить, как решить проблему, с которой я имею дело. Это, вероятно, связано с тем, что все еще очень плохо знаком с JavaScript. В любом случае, ниже приведен код, который я написал:

    var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR'

    var request = new XMLHttpRequest();
    request.open('GET',requestURL,true);
    request.responseType = 'json';

    request.onload = function(){ 
        var data = request.response; 
        console.log(data); 
    }


    request.setRequestHeader('Access-Control-Allow-Origin','*');

    request.send(); 

1 ответ

Решение

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

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

var proxyURL = 'https://cors-anywhere.herokuapp.com';
var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR';
var request = new XMLHttpRequest();
request.open('GET', proxyURL + '/' + requestURL, true);

Это отправляет запрос через https://cors-anywhere.herokuapp.com/, который направляет запрос в https://api.kraken.com/0/public/OHLC?pair=ETHEUR а затем получает ответ. https://cors-anywhere.herokuapp.com бэкэнд добавляет Access-Control-Allow-Origin заголовок ответа и передает его обратно запрашивающему коду интерфейса.

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

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

Обратите внимание, что request.setRequestHeader('Access-Control-Allow-Origin','*') необходимо удалить из кода внешнего интерфейса, с которым вы делаете запрос (как указано в комментариях выше).

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

Для получения подробной информации о том, что делают браузеры, когда вы отправляете запросы из разных источников из кода JavaScript внешнего интерфейса с использованием XHR или методов Fetch API или AJAX из библиотек JavaScript, а также сведения о том, какие заголовки ответов необходимо получать, чтобы браузеры позволяли коду внешнего интерфейса получать доступ к ответы - см. https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS.

var proxyURL = 'https://cors-anywhere.herokuapp.com';
var requestURL = 'https://api.kraken.com/0/public/OHLC?pair=ETHEUR';

var request = new XMLHttpRequest();
request.open('GET', proxyURL + '/' + requestURL, true);
request.responseType = 'json';

request.onload = function() {
  var data = request.response;
  document.querySelector('pre').textContent = JSON.stringify(data, null, 2);
}

request.send();
<pre></pre>

Другие вопросы по тегам