outbreak

Me

My name is Marko Mrdjenovič. I’m a web developer, manager and an entrepreneur from Ljubljana, Slovenia.

Bio

I like solving problems. I do that by writing code, managing projects and people. I like creating good experiences. And going to conferences.

Availability

I work full time on Klevio so I'm currently not available for freelance work (UX, frontend, backend).

Elsewhere:
LinkedIn
Twitter
Facebook
Quora
Flickr

Archives

The Cross-Origin Request Sharing (CORS) knot

As a developer for a company that does a lot of cross-domain posting I was happy to see CORS finally happening. I’ve authored jQuery.windowName plug-in to add support for cross-domain posting in the past and this was my way out – no more hacks as browser support for CORS grows.

Yeah right.

CORS is supported on XMLHttpRequest object in Gecko and Webkit. You just request something on a different domain, and if the response has the right header with the right value you get the data. In IE you have to use a new object called XDomainRequest which is somewhat similar to XMLHttpRequest, but without readystate, onreadystate event handler and basically any header getters/setters.

Sounds ok and when I first tried it I was quite happy with how it worked. But unfortunately nothing is that simple in the land of browsers. When it fails, it’s a whole new game…

Gecko (Firefox)

Same domain request:
Cross domain request with proper headers:
Cross domain request without proper headers:

Webkit (Safari, Chrome)

Same domain request:
Cross domain request with proper headers:
Cross domain request without proper headers:

IE

Same domain requests made with XMLHttpRequest, cross domain requests made with XDomainRequest.

Same domain request:
Cross domain request with proper headers:
Cross domain request without proper headers:

Where’s the knot?

The problem with this is the lack of error handling. Firefox will return status 0 on all errors, but will indicate what the response was with statusText. It will also return 0 on a 304 response, which is a bit weird. Webkit on the other hand only returns status 0 on failed requests, but without telling you what’s wrong. You get the same error when a preflight request fails, a 500 error on the server or the real request fails. IE with its own separate XDomainRequest implementation simplifies this two handlers – onload and onerror. Unfortunately it raises an onerror request when a 304 is returned on empty cache.

jQuery issues

If you’re working with jQuery (and possibly other libraries) you’re in for a treat. Opera 9.5 falsely reports status = 0 when a HTTP status 304 is returned from the server. For this reason jQuery treats status === 0 as a successful request. Thus you have no way of knowing whether your request was a success or a failure.

Untying the knot

If you intend to use jQuery’s built-in methods you’ll need to do your own bookkeeping:

  1. Know when a request is a CORS request
  2. Wait for complete event
  3. If data is empty trigger error handling

For this to work you obviously always need some data. If empty data is valid you’re screwed.

Easy way out

You might have noticed before that I made a jQuery.windowName plugin. It still has the same name, but now also supports CORS requests and does some of the CORS related bookkeeping. As the latest version is still in testing you can get it directly at http://friedcell.net/js/jQuery.windowName/jQuery.windowName.plugin.1.0.0.js (test page).

Enhanced by Zemanta

Opinions

express yours below

Express your opinion