unseen complications

Don’t you hate the unseen complications that rear their ugly heads somewhere down the line?  Today’s drama involved the inclusion of a very cool fullscreen api by Vincent Guillou.  Of course, it worked great in development and then failed silently on production.  Here is an overview of what makes my production site a little different.

Production Site Overview

GoDaddy domain name hosting with option “forwarding with masking” —> Firebase.com—based hosting site

GoDaddy does this technically by serving up a single HTML page which simply frames the remote content.  By its nature, it uses the HTTP protocol and cannot use HTTPS. In its configuration it allows you to set either HTTP/HTTPS for the framed content, however.  You’d think that you would have plenty of room to make something work. And it did work just fine up until the latest add to the project:  a button which allows the browser to go full screen and back again.

Unfortunately, the first push to production then failed silently. The button was there but didn’t seem to work. Entering the development area of the browser I saw that the browser had to block the content because the framing page was HTTP and the framed content was HTTPS and this isn’t allowed.

Okay, so I thought I could then adjust GoDaddy’s settings so that I could frame the content as HTTP to match the parent document. Unfortunately I see that Firebase always uses HTTPS and does not support HTTP. Since I can’t mis-match the content and combined with the fact that I can’t easily promote GoDaddy to HTTPS on the framing page or demote Firebase on the framed page, I was screwed.

To make a long story short, I either had to pay for hosting at Firebase (which allows you to bind your domain name to their hosting server) or I could abandon the cool  feature. Since I’m trying to highlight the cool new features of the latest browsers I decided that’s it’s better to just pay Firebase in this case.

It was still a bit technical in getting all this to work since Firebase only bound a single entity (www) to the website using my domain. This means that if someone just puts in my domain name only then they’re stuck at a GoDaddy-parked page. To work around this problem, I set up a redirect to deal with this situation. This time it looked like:  myJS.io -> http://www.myJS.io. Problem solved.

So now, the cool new feature is working on production and the implementation is slightly simpler, not that anyone else would necessarily know.

cross-origin resource sharing

I keep finding myself going over to the Enable CORS website to copy/paste their example code into my server-side.  They’ve saved me more than once.

Yet again today I was momentarily flummoxed over some seemingly-correct Javascript code in a PhoneGap project to fetch a json response from the server.

 $.getJSON(strURL, function(jsonData) {
  // Do nothing at this level but wait for the response
  }).done(function(jsonData) {
    // Do something upon success
  }).fail(function(XMLHttpRequest, textStatus, e) {
    $('#homeStatusParagraph').html('Lookup failed,
      status=[' + textStatus + '], error=[' + e + ']');
  }).always(function(jsonData) {
    // Do nothing here
 });

Interestingly, the fail() code section ran instead of the expected done() section.  At this point I then made the call manually to the server address represented in the strURL variable and it returned exactly what I thought it would, a json-formatted document.

The status returned from getJSON() was simply error and the returned e object was empty, not very useful for troubleshooting this.  What’s actually going on is that the client-side browser is blocking the inclusion of json fetched from another computer, presumably for security reasons.

Fortunately I’ve dealt with this before and inserted the code in green below to my Node.js server’s app.js file.

app.use(passport.initialize());
app.use(passport.session());
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers",
    "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
var routes = require("./routes/index");

This immediately fixed the problem and getJSON() on the client now happily worked, parsing the response from the server.