Monthly Archives: December 2013

The Agony and the Ecstasy of Ext 4, IE 8, and CORS

We’re currently working on an Ext 4 project that makes cross-domain requests to a .NET server. One of the restrictions on the app is that it must work with Satan’s favorite browser – IE 8.

Normally, this isn’t a huge challenge – but in this case, we’re working in a mixed environment – users actually login to a ColdFusion server (www.client.org), however, the webservices supporting our Ext app are running on a subdomain (e.g. webservices.client.org) in a .NET environment.

Rather than using JSON-P based services, we decided to go with a CORS-based solution. Users receive a domain-cookie from the ColdFusion server, which would be transparently passed to the .NET webserver. The .NET server, in turn, makes a callback to the CF server to validate the session.

By default, Ext 4 will *not* transmit cookies on AJAX requests. The key to solving this particular issue was to override the Ext.data.Connection class and force the withCredentials property to true.

Ext.define('MyApp.override.DataConnection', {
 override: 'Ext.data.Connection',
 withCredentials: true
});

So that worked great in Chrome…and every other browser…except the hellspawn.

It turns out that if you want to make CORS requests from Ext in an IE 8 environment, you’ve got to set the cors=true property on the Ext.data.Connection class. This causes IE 8 to use its XDomainRequest object instead of XMLHttpRequest (like every other non-Microsoft browser) because back in the heady days of IE 8, Microsoft owned the Internet. And everyone else could suck it.

So…back to our DataConnection Override:

Ext.define('MyApp.override.DataConnection', {
 override: 'Ext.data.Connection',
 withCredentials: true,
 cors: true
});

However, IE *still* wasn’t passing the cookie…well, it turns out that IE 8’s XDomainRequest object will not pass cookies under any circumstances because Google Chrome was just a glimmer in Sergey Brin’s eyes at the time.

SO…ultimately the solution was to override our Ext AJAX proxies to always transmit the cookie over the URL. A ridiculous kludge for a ridiculous browser.

Ext.define('MyApp.override.AjaxProxy', {
    requires: ['Ext.util.Cookies', 'Ext.Ajax'],
    override: 'Ext.data.proxy.Ajax',
    constructor: function(config) {
        var me = this;
        config = config || {};
        me.callParent([config]);
        me.extraParams = config.extraParams || {};
        
        
        if (Ext.isIE8) {  // Steve Ballmer can bite me
          Ext.apply(me.extraParams,{
           'JSESSIONID' : Ext.util.Cookies.get('JSESSIONID')
          });
        }

        me.api = Ext.apply({}, config.api || me.api);
        
        //backwards compatibility, will be deprecated in 5.0
        me.nocache = me.noCache;
    }
});

Oh, and one more thing — I wouldn’t have been able to troubleshoot this without using Fiddler: http://fiddler2.com/. As it turns out, the IE 8 debugger doesn’t support showing http traffic. After all, why would a web developer need an http traffic analyzer built into their web browser? That’s just crazy talk.