In this series I attempt to complete Free Code Camp as quickly as possible, without cutting too many corners. For an introduction to this series, see Free Code Camp #0: Speedrunning Free Code Camp.

In this entry I will create a small website that shows the weather at the user's current location.

CORS problems

I first started out with the Norwegian Meteorological Institute (MET) API. The API support neither CORS or JSONP, so all requests need to be proxied. As a further complication, use of the location API in web browsers now requires HTTPS, and will fail on HTTP sites. The best CORS proxy I found was Crossorigin.me, but unfortunately it went down before I could finish the weather app. CORS, in a nutshell, works like this:

  1. Try to send a GET request to https://crossorigin.me/http://no.cors.api/ using Ajax. Our web browser intercepts the request and sends an OPTIONS request instead.

  2. The proxy replies with Access-Control-* headers specifying that, yes, it is safe (according to the API) to send a GET request to this origin. Finally we get to GET the API (via the CORS proxy).

  3. If you aren't using a CORS proxy and the site doesn't provide the appropriate Access-Control-* headers, the browser will just refuse to complete the request. Whoops.

Parsing weather XML

Apps living outside web browsers can choose to skip the whole CORS-dance, and this is exactly what the proxy does for us.

The MET API endpoint I used was: https://crossorigin.me/https://api.met.no/weatherapi/locationforecast/1.9/?lat={0};lon={1};. The results are the current forecast in XML format, but it's nothing jQuery can't handle. A little excerpt from my code:

  weather.temp = f($loc.find("temperature").attr("value"));
  weather.tempUnit = $loc.find("temperature").attr("unit");
  weather.windDirection = $loc.find("windDirection").attr("name");
  weather.windSpeedMPS = f($loc.find("windSpeed").attr("mps"));
  weather.windSpeedBeaufort = f($loc.find("windSpeed").attr("beaufort"));
 ...

Ignore CORS in Chrome

After the CORS proxy went down, I was stuck for a while, since I didn't want to make one myself. There is alternative solution however: This Chrome extension adds the possibility to ignore the CORS-dance, letting any XMLHTTPRequests do whatever they want to, without asking the server for permission first.

After dealing with these CORS issues, I could finally complete the website.

See the code on CodePen.

The left table shows most of the data returned for the current time, while the right column shows a graphical representation. Clicking on the termperature toggles betwen Celsius and Fahrenheit. There is an API endpoint for weather icons at: https://api.met.no/weatherapi/weathericon/1.1/?symbol={0};content_type=image/svg%2Bxml. The symbol parameter is given in the weather data. Example:

I spent more time than expected on this, so I'll have to catch up in the next challenges.

Next entry: A Wikipedia Viewer