title: How to get data from an external provider in CodePen?
body: <p>I'm doing the JavaScript challenges at <a href="https://www.freecodecamp.com/dpisarenko" rel="nofollow noreferrer">FreeCodeCamp</a>. One of them is to create a web page that retrieves and displays weather information.</p>
  
  <p>First, I tried to use several providers (e. g. OpenWeatherMap, <a href="https://www.wunderground.com/weather/api/d/docs?d=resources/code-samples" rel="nofollow noreferrer">WeatherUnderground</a>), which use the HTTP protocol to return weather data. It didn't work because of the <a href="https://developers.google.com/web/fundamentals/security/prevent-mixed-content/fixing-mixed-content" rel="nofollow noreferrer">mixed content</a> error.</p>
  
  <p>Next, I switched to a provider, which delivers the data via HTTPS. I got rid of the mixed content problem, but got another one:</p>
  
  <blockquote>
    <p>XMLHttpRequest cannot load <a href="https://api.weatherbit.io/v1.0/current?lat=55.7767723&amp;lon=37.6090795&amp;units=S&amp;key=XXXXXXXX" rel="nofollow noreferrer">https://api.weatherbit.io/v1.0/current?lat=55.7767723&amp;lon=37.6090795&amp;units=S&amp;key=XXXXXXXX</a>. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '<a href="https://s.codepen.io" rel="nofollow noreferrer">https://s.codepen.io</a>' is therefore not allowed access. The response had HTTP status code 403.</p>
  </blockquote>
  
  <p>I tried to implement CORS according to <a href="https://www.html5rocks.com/en/tutorials/cors/" rel="nofollow noreferrer">this tutorial</a>:</p>
  
  <pre><code>function createCORSRequest(method, url) {
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr) {
  
      // Check if the XMLHttpRequest object has a "withCredentials" property.
      // "withCredentials" only exists on XMLHTTPRequest2 objects.
      xhr.open(method, url, true);
  
    } else if (typeof XDomainRequest != "undefined") {
  
      // Otherwise, check if XDomainRequest.
      // XDomainRequest only exists in IE, and is IE's way of making CORS requests.
      xhr = new XDomainRequest();
      xhr.open(method, url);
  
    } else {
  
      // Otherwise, CORS is not supported by the browser.
      xhr = null;
  
    }
    return xhr;
  }
  
  [...]
  
  var url = "https://api.weatherbit.io/v1.0/current?lat=" + position.coords.latitude + "&amp;lon=" + position.coords.longitude + "&amp;units=S&amp;key=XXXXXXXX";
  var xhr = createCORSRequest('GET', url);
  if (xhr) {
      xhr.onload = function() {
        var responseText = xhr.responseText;
        console.log("Response: " + responseText);
      };
  
      xhr.onerror = function() {
        console.log('There was an error!');
      };
      xhr.send();
  }
  </code></pre>
  
  <p>When I call <code>xhr.send()</code> I still get the error.</p>
  
  <p>How can I fix it?</p>
  
  <p>Note: I'm looking for a solution that will run in <a href="http://codepen.io/" rel="nofollow noreferrer">CodePen</a>.</p>
  
  <p><strong>Update 1 (23.03.2017 11:35 MSK):</strong> I tried to implement sideshowbarker's answer and modified the code like this:</p>
  
  <pre><code>function getCurrent(json){
       console.log("getCurrent called");
       console.log(json.data.temp);
       console.log(json.data.precip);
  }
  
  function updateWeather() {
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(function(position) {
        var url = "https://api.weatherbit.io/v1.0/current?callback=getCurrent&amp;lat=" + position.coords.latitude + "&amp;lon=" + position.coords.longitude + "&amp;units=S&amp;key=XXXXXXXXX";
        console.log("url: " + url);
        $.get(url, function(val){});
      });
    } else {
      console.log("Cannot obtain location data");
    };
  }
  
  updateWeather();
  </code></pre>
  
  <p>The result:</p>
  
  <p><a href="https://i.stack.imgur.com/8sdPG.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/8sdPG.png" alt="Screenshot with error messages"></a></p>
  
  <p><strong>Update 2 (23.03.2017 13:29 MSK):</strong> This one works.</p>
  
  <pre><code> function getCurrent(json) {
     console.log("getCurrent called");
     console.log(JSON.stringify(json));
     // TODO: Update the UI here
   }
  
   function updateWeather() {
     if (navigator.geolocation) {
       navigator.geolocation.getCurrentPosition(function(position) {
         var url = "https://api.darksky.net/forecast/XXXXXXXXX/37.8267,-122.4233?callback=getCurrent";
  
         var script = document.createElement('script');
         script.src = url;
  
         document.getElementsByTagName('head')[0].appendChild(script);
  
       });
     }
   }
  
   updateWeather();
  </code></pre>