Данные API через http на сайте, обслуживаемом через https, скрипт содержит ошибку смешанного содержимого

Я написал сценарий JS, который использует данные из http API (конечная точка для запроса GET: http://api.open-notify.org/iss-now.json). Я намереваюсь использовать его на странице, размещенной на страницах github (которая использует протокол https).
Теперь, когда он подключен к сети, я вижу в консоли, что эти данные нельзя использовать в браузере из-за ошибка смешанного активного содержимого: Blocked loading mixed active content “http://api.open-notify.org/iss-now.json”.

Я не могу применить это решение, потому что я не использую файл server.js (мой контент обслуживается гитхаб). Я хотел попробовать это другое решение, но для этого требуется открыть страницу адаптера на другой вкладке, что просто нежизнеспособно. Я пытаюсь использовать это обходной путь, но https://cors-anywhere.herokuapp.com/http://api.open-notify.org/iss-now.json возвращает ошибку (отсутствует обязательный заголовок запроса. Необходимо указать один из: origin,x-requested-with). Если кто-нибудь знает, как добавить заголовки в метод loadJSON, скажите, пожалуйста, я ничего не могу найти в его документации. Мне не очень нравится синтаксис fetch, поэтому, когда я пытаюсь это сделать:

 var response = fetch("https://cors-anywhere.herokuapp.com/http://api.open-notify.org/iss-now.json", {
    headers: {
      Origin: window.location.protocol + '//' + window.location.host
    }
  });
  if (response.ok) { // if HTTP-status is 200-299
    // get the response body (the method explained below)
    var json = response.json();
    return(json);
  } else {
    alert("HTTP-Error: " + response.status);
  }

Я добавляю заголовок источника только для того, чтобы обнаружить, что

Запросы между источниками заблокированы: та же политика происхождения запрещает чтение удаленного ресурса по адресу https://cors-anywhere.herokuapp.com/http://api.open-notify.org/iss-now.json.. (Причина: заголовок CORS «Access-Control-Allow-Origin» отсутствует). Что, насколько я понимаю, можно исправить только на стороне сервера. Страница github cors-anywhere рекомендует реализовать их решение в вашем собственном скрипте, добавив этот фрагмент:

(function() {
    var cors_api_host = 'cors-anywhere.herokuapp.com';
    var cors_api_url = 'https://' + cors_api_host + '/';
    var slice = [].slice;
    var origin = window.location.protocol + '//' + window.location.host;
    var open = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function() {
        var args = slice.call(arguments);
        var targetOrigin = /^https?:\/\/([^\/]+)/i.exec(args[1]);
        if (targetOrigin && targetOrigin[0].toLowerCase() !== origin &&
            targetOrigin[1] !== cors_api_host) {
            args[1] = cors_api_url + args[1];
        }
        return open.apply(this, args);
    };
})();

но я бы не знал, как это реализовать, мне пока не удалось интегрировать его в свой код.

Мой код сейчас немного запутан, но я могу показать вам следующее:

// global functions for the Tracker sample
function getData() {
  // var promise = fetch("http://api.open-notify.org/iss-now.json");
  loadJSON("http://api.open-notify.org/iss-now.json", gotData, 'jsonp');
}

function gotData(data) {
  background(img)
  displaySample()
  // this will allow you to see the raw data live in your browser console
  //console.log(data.iss_position.latitude);
  //console.log(data.iss_position.longitude);
  posX = (parseFloat(data.iss_position.latitude * latConst) + translateX)
  posY = (parseFloat(data.iss_position.longitude * lonConst)* -1 + translateY)
  console.log(posX);
  console.log(posY);
  fill(250, 50, 50, 90);
  ellipse(posX, posY, 10, 10);
}

function draw() {
  // case tracker
  if (selectedSample === 1) {
    translateX = boxSizeWidth / 2;
    translateY = boxSizeHeight / 2;
    latConst = boxSizeWidth / 360;
    lonConst = boxSizeHeight / 180;
    if (t === 0) {
      getData()
    }
  }

Я также пытался найти https API, предоставляющий те же данные (широту и долготу МКС в реальном времени), но сейчас я не могу их найти, и в любом случае было бы интересно найти обходной путь.


person WildWilyWilly    schedule 12.12.2020    source источник


Ответы (1)


Вы можете использовать fetch следующим образом:

fetch("https://cors-anywhere.herokuapp.com/http://api.open-notify.org/iss-now.json", {
    headers: { Origin: window.location.host }
  })
  .then(res => res.json())
  .then(res => {
    console.log(res);
    // gotData(res);
  })
  .catch(err => {
    console.log(err);
  });

person blex    schedule 12.12.2020
comment
Ура! Работает как шарм. Мне действительно нужно научиться использовать fetch(), сохраняя при этом простоту, моя попытка реализации была ужасной. - person WildWilyWilly; 13.12.2020
comment
Вы привыкнете к этому :) Нет необходимости проверять, есть ли response.ok или есть ли ошибка, прежде чем использовать ответ, потому что, если запрос не удался или если ответ не может быть проанализирован, ваши then не будут выполняется, он попадет прямо в catch, если есть ошибка - person blex; 13.12.2020