IE seems right, Chrome seems wrong

October 10, 2013

At Clef, we work with a lot of iframes. If you use our easy-install button, whenever you click it, you’re really clicking an iframe, which communicates with the main window (the page you’re currently on), which opens another iframe (the overlay with the Clef Wave) that allows you to sync and log in. Behind the scenes, all of this is accomplished with postMessage — a javascript browser API that allows developers to “safely enable cross-origin communication.” In other words, it allows the iframes that hold our button and Wave to communicate safely with the page they are hosted on.

We broke Clef

A few weeks ago, after deploying some changes to our javascript, an Internet Explorer user notified us that we’d completely broken Clef — when they clicked the button, nothing happened. We weren’t seeing any issues in Chrome, Safari, Firefox, so we quickly assumed that we’d hit an IE “idiosyncrasy” that we would have to work around. Digging a little deeper, we found the source of the problem.

When we’re using postMessage, we need to make sure you’re not interpreting other people’s messages (Facebook posts a ton). For this reason, we verify that the message is coming from our domain (‘https://clef.io’), and if it isn’t, return. Examining the code execution in IE, we noticed that when our message was posted, it failed this test and returned — thus, the window did nothing. What was going on?

host vs. hostname

Host contains the port, while hostname does not…or at least that’s what is supposed to happen. In our normalize function, we use an HTML link attribute to parse out the host and protocol of the origin where the event came from. Examining our code, we quickly realized that we had a bug — if host contains the port (the correct behavior), the domain check would fail (‘https://clef.io:443′ != ‘https://clef.io’).

Strangely enough, everything was working fine in Chrome, but seemed totally broken in IE. Let’s take a look at how the two browsers handle the host attribute.

Internet Explorer 10

Screen-Shot-2013-10-10-at-8.57.44-AM

Chrome 30

Screen Shot 2013-10-10 at 8.56.55 AM

Uh oh. Can you spot the difference? For both HTTP and HTTPS connections, Chrome scrubs the port number from host if it’s the default (80 for HTTP, 443 for HTTPS) — even if you explicitly specify it. If you use a non-default port number, it always includes it.

Screen_Shot_2013-10-10_at_8.56.55_AM

That doesn’t seem correct. When no port number is specified, it’s debatable whether host should include the port (IE obviously extrapolates it from the default port for the protocol). If a port number is specified, it should absolutely be included in the host.

My usual resource (MDN) for documentation on web things was surprisingly unhelpful with this issue. Their page on the host attribute has an example, which has a typo (assumes port 80 for HTTPS) and doesn’t work correctly in Chrome or Firefox (it follows the IE behavior).

From the looks of it, Chrome was wrong and IE was right.  That being said, I’m not 100% sure what’s going on here — is this a bug in Chrome and Firefox or am I misunderstanding something?

Can you help me figure out what’s going on?

I’m not an expert on browsers, so I’d love to hear from someone who is. Why is there this discrepancy? Is one implementation more correct than the other?

Let me know what you think on Twitter or Hacker News.

WordPress Login Protected by Clef