Search code examples
javascriptapicorsp5.jsmixed-content

API data over http in site served over https, script has "mixed content" error


I've written a JS script that consumes data from an http API (endpoint for the GET request: http://api.open-notify.org/iss-now.json). I intend to use it in a page hosted on github pages (which makes use of the https protocol).
Now that it is online I see in the console that this data can't be used in-browser because of the mixed active content error: Blocked loading mixed active content “http://api.open-notify.org/iss-now.json”.

I can't apply this solution because I'm not making use of a server.js file (my content is served by github). I wanted to try this other solution but it requires opening the adapter page in another tab, which just isn't viable. I'm trying this workaround but https://cors-anywhere.herokuapp.com/http://api.open-notify.org/iss-now.json returns an error (Missing required request header. Must specify one of: origin,x-requested-with). If anyone know how to add headers to the loadJSON method please tell me, I can't find anything in its documentation. I'm not exactly at ease with the syntax of fetch, so when I try it:

 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);
  }

I get to add the "origin" header, only to find myself with a

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://cors-anywhere.herokuapp.com/http://api.open-notify.org/iss-now.json. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing) Which as far as I understand can only be corrected server-side. The github page of cors-anywhere encourages to implement their solution in your own script, by adding this snippet:

(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);
    };
})();

but I wouldn't know how to implement it, I haven't succeeded integrating it in my code for now.

My code is a bit of a mess right now but I can show you this much:

// 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()
    }
  }

I also tried finding an https API giving the same data (latitude and longitude of the ISS in real time) but I can't seem to find any for now, and finding a workaround would be interesting anyway.


Solution

  • You could use fetch like this:

    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);
      });