Arrow

Cross-domain Ajax calls in Internet Explorer 8 and 9

First published on June 16, 2013

I was working on a site (let’s say www.site.com) that had a multi-page quiz feature. Once you are done with the quiz, the results page tells you how you did but also posts your score to a separate domain (let’s say community.site.com) in order to record your score. It also shows you the average score for that quiz based on the JSON response from community.site.com/. This requires sending information to that separate domain and also parsing the response from that domain.

If you are using jQuery, this is rather standard behavior and well-documented. Here’s an example of the JavaScript call:

jQuery.ajax(
{
	type     : 'GET',
	url      : methods.options.quiz_add_result_url,
	data     : { quiz_id : quiz_id, score : ( score_per_cent / 100 ) },
	dataType : 'json',
	timeout  : 4000
})
.done( function( data ) { methods.updateAverageQuizScore( data ) } );

The important additional element is to use cross-origin resource sharing (CORS) by setting the Access-Control-Allow-Origin header in the response.

Here is a PHP example:

$allowedHTTPReadOrigins = array( 'http://www.site.com' );
$requestHeaders = apache_request_headers();
if(
	isset( $requestHeaders[ 'Origin' ] ) &&
	in_array( $requestHeaders[ 'Origin' ], $allowedHTTPReadOrigins ) )
{
	header( 'Access-Control-Allow-Origin: ' . $requestHeaders[ 'Origin' ] );
}

This is enough for the general framework to work for all modern browsers except for IE8 and IE9. I’d tested a few suggested fixes such as forcing the “cors” settings in jQuery, and setting the data type of the request and response to “text”. Some combination of tweaks allowed the Ajax request to be sent, but the response was never being parsed. JSONP is an alternative where the response data executes a callback function. However, I ended up using Internet Explorer’s XDomainRequest object handle the Ajax call. I don’t like the fact that I have two versions of the same Ajax call (one with the standard jQuery Ajax call and one using XDomainRequest) but it successfully makes the call and parses the response:

// average score
// IE8 and IE9
if( 'XDomainRequest' in window && window.XDomainRequest !== null )
{
	var xdr = new XDomainRequest();
	if( xdr )
	{
		xdr.onload = function() { methods.updateAverageQuizScore( jQuery.parseJSON( xdr.responseText ) ); };
		xdr.open( 'GET', methods.options.quiz_add_result_url + '?quiz_id=' + quiz_id + '&score=' + ( score_per_cent / 100 ) );
		xdr.timeout = 4000;
		xdr.send();
	}
}
else
{
	jQuery.ajax(
	{
		type     : 'GET',
		url      : methods.options.quiz_add_result_url,
		data     : { quiz_id : quiz_id, score : ( score_per_cent / 100 ) },
		dataType : 'json',
		timeout  : 4000
	})
	.done( function( data ) { methods.updateAverageQuizScore( data ) } );
}
Arrow

Speak your mind

*
To prove you're a person (not a spam script), type the security word shown in the picture. Click on the picture to hear an audio file of the word.
Click to hear an audio file of the anti-spam word