A Fun Little JSON Murder Mystery With IE9

Fuck You IE.

That’s what I said about every 20 seconds as I sit there, beer in hand, neck getting stiff from staring at my screen.

“If you keep pounding your keyboard like that I have a feeling you’ll be ordering Yet Another Macbook tomorrow. Do you think we can keep this one alive just a bit longer?”. That’s my wife. She’s awesome. She deals with me and my frustrations with the skill of a scarred snake handler. “Blmrmrpmrnrghrhrr fuckin IE9” is all I can muster in response… making sure to keep my voice low so my venom stays clear of little ears.

Like many developers with thick, rough scars from dealing with framework inconsistencies and crashing applications: I know. I leave room for what I think will be inevitable: That this is all my fault. Somehow.

I can taste the bile in my throat: I don’t want to be wrong. I want to ignite a million tons of TNT under IE9’s decaying carcass and vault it into the Sun’s core. A nice, lazy arc so it has time to think about the tears shed in its presence over the years… and perhaps reflect on the hard black nut that represents its existence.

But yet… there’s that damn voice in the back of my mind… I know… I know…

Let’s Take a Look At Those Headers

The last thing you ever want to hear is a positive voice when you’re nuclear. I was beyond nuclear – I might have actually been nucular.

One of the hard things about writing a blog in a “no BS” style is people tend to think that’s your default. That you’re “always nuclear dude”… confusing plain-spoken with “cranky” happens a lot to me. I’m used to it.

This is different. I was pissed. But it’s occurring to me that you probably don’t know why – so let me explain.

I just updated Tekpub in response to some Rug-Pulling gymnastics, courtesy of the Shopify API team and their arrogance. More on that later. So I had a little extra juice in my cup already.

I decided to get around some SSL/Flash issues with Rails and use Ajax/JSON for the site’s cart interactions. We’re using Rails, I develop on a Mac and the short story is that all worked really well in Chrome/Safari/WebKit/Firefox.

And then I received a cranky email from a potential customer (paraphrasing):

I want to buy one of your productions but you don’t seem to test your own shit – especially for the browser with the highest marketshare.

He was talking about IE9, and the fact that he couldn’t add something to his cart as my scripts were failing. Hrrmph.

A sale not going through and a cranky customer. Blood pressure rising… can this be right? I kept to jQuery’s core functionality to avoid any browser weirdness… I’m not doing anything extraordinarily strange here… WTF?

Dammit. Dude was right: IE9 was silently failing when user’s tried to add something to their cart. When I say “silently failing” I mean that literally – there was no console error trace, no log file issues on my server that would indicate a bad request of some kind. it just didn’t work.

I set a break point in the script using IE9’s dev tools (which are pretty nice, I must say) and through an increasing sweat I watched as the $.post call to my server just… failed. And by “failed” I mean “nothing happened”. Void. Silence.

Fuckin IE

My users are trying to buy things and I’m letting them down. I hate IE9 for this, but I also know that I can’t blame IE9 for my failure to account for its shittiness – this is my fault. Dude was right – I didn’t check everything as thoroughly as I should have. I’m an idiot.

That’s why I was nuclear. I felt dumb. I felt let down. I was mad at myself for being rushed and I really wanted to keep my users happy… Now I need to fix this.

I opened up my server log to see if IE was indeed phoning home:

tail -f logs/production.log

And now I’m watching green text scroll by on my terminal. Blond, brunette, red-head… they’re all using Tekpub according my production.log.

I take a deep breath, trying to clear my thoughts and calm down. My wife has taken the kids outside to play with our dog, leaving me to my grumbles. I click on the “Add To Cart” link.


Started POST "/orders/add_item" for at 2011-10-18 19:52:31 +0000
  Processing by OrdersController#add_item as JSON
  Parameters: {"id"=>"29"}
Completed 200 OK in 118ms (Views: 0.3ms | ActiveRecord: 1.0ms)

You little shit. You rusty, crusty piece of shit! IE9 has indeed completed the $.post – and THEN FAILED. Is there a word for this? Fuccess? That word seems to fit:

IE9 Fuccessfully sent a post off and did what it needed to do which is “fail completely” evidently. I’m pretty sure I’ve fallen into a major bug. I’m very sure I don’t know what’s going on so I call Batman. You guys call him Dave WardI call him Batman cause the guyhas TRICKS.

We get on Skype and he’s Mr. Jovial. Batman likes to solve crimes and I think he was bored. I don’t want to hear jovial, happy, or anything other than “Yeah your’re right – IE9 is full of bugs.”

So that’s where I start off. A short tour of the code, I show him my break-point dancing, and finally a summary that goes something like

As you can see, my code’s awesome and perfect. IE9 is a pile of trash smoldering inside a wet blanket full of sweaty meat that’s been sitting in the sun for 3.5 weeks in Toronto. No, make that Florida.

Dave then casually asks me to add some error trapping code for the response. I had planned for errors from my server – but not errors from the browser. Another dumb thing. So I add “status” and “message” to the Ajax error handler code:

cart = {
    addItem : function(productionID){
          type: 'POST',
          url: "/orders/add_item",
          data: { id : productionID },
          success: function(data){
                notifier.success("Item Added...");<br />
            error : function(xhr,status,message){
                notifier.error("Sorry looks like an error occurred.");
            dataType: "json"

I put a break-point in the error handler and click “Add To Cart” again – and the error handler gets tripped. I hover over the “message” variable and both of us stare at … what can only be described as “sub-optimal”

error on internal operation c009eurk

I tried to snap a screenshot of this but got distracted.

Batman laughs. I groan. We make jokes about Outlook Express. I feel lost and hopeless, Batman is getting more and more excited. After a few seconds he says, quietly:

Let’s have a look at those headers.

Charsets. It’s Always Charsets.

I crack open the debugger tools my local browser (Chrome for Mac) using Command-Option-I and click over to Network. I click on the “Add To Cart” link again and, with a small feeling of triumph I see the cart stuff flash about all over the page, and in the debugger window I see all kinds of requests and resources fly by.

I click on the call to “orders/add_item” and in there I see this:


Batman seems to know what’s going on. This makes me happier. “IE9 has a notoriously strict JSON parser”.


Turns out

Jon Gallowaylikes reading specs. So much so, that he this little nugget which, oh dear, might identify a bug in IE 9.

Indeed it does. The orders/add_item call returns a valid set of JSON – the items in the cart – that the page should refresh with. IE9, however, doesn’t know what to do with this perfectly valid JSON. Its parser doesn’t know what character set it should use to deserialize it.

In short: the POST was a success – the item was added to the cart. But IE9 didn’t understand how to parse the response so it stopped processing it. IE9 does know that it’s JSON but it doesn’t know what character set to use to decode it.

So it refuses to do it. It’s not an error – it’s a refusal. That’s weird.

It’s at this point that little voice returns. According to the specs – indeed I’ve been doing it wrong. Chrome/Webkit/Firefox have been nice to me, using my Mac’s system defaults to figure out how to decode the returned JSON. Either I don’t have that setting in IE9 (or my VM’s Control Panel) – or IE9 isn’t able to do it. To be honest, I really don’t care – at this point I need it fixed and figuring out why is bumming me out.

What I need to do is force the issue. I need to tell the browser what charset to use – and to be frank I’m a bit surprised that Rails doesn’t do this by default (I’m using Rails 3.0.9). To be clear, I have encoding set:

# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"

I don’t have a default character set … set. With a little Googling, Batman finds a solution:

# set in config/application.rb

config.action_controller.default_charset = "utf-8"

Resart my local server, and BAM – everything works:


I deploy the app to Tekpub.com – the 15th deployment in the last 2 hours. I mutter a few pointless threats to IE9 as I wait patiently for the app to spool up. I reach for that damned blue E icon with my mouse as if I’m picking up something that just dropped out of the back of my dog… and I click on it. MSN is in front of me… grumble grumble… and I head over to Tekpub.com. Batman watches all this quietly.

I click add to cart. And… there it is:

It works.

I breathe out. I tell Batman I love him. He simply says “it’s what I do.”

You Say Standards, I Say…

In retrospect – IE9 was doing what it should have done: It won’t deserialize an unknown blob of bytes. IE9 is kind of like a honey badger in this way: it really couldn’t give a shit. My server should be sending back a valid header – end of story.

And it’s probably right. IE9 is simply following the rules and the IE team can boast about how standards-compliant IE is, even if it causes abnormal behavior and cruciferous error messages straight out of 1994. So, ultimately – I’m the one who’s wrong here. Just as I expected.

Either way, the problem is fixed. It would be nice to see some type of proper error message generated so that dudes like me, who aren’t up on the JSON spec, can figure out the problem more readily. Perhaps that’s coming in IE10 and it’s “native JSON experience”. Either way, my problem is solved.

I tell Batman he should write a post about this. JavaScript is his deal. Batman laughs at me.

I don’t know shit about Ruby. That’s your deal.

I suppose. Batman has his ways.