Wednesday, March 5, 2008

Cross-Browser AJAX

I am celebrating right now because I found a work-around for a very strange problem I've been having regarding AJAX and Internet Explorer's general noncompliance with the world. This has literally been on the critical path in my senior design project for months, and seemed to have cropped up out of nowhere. Let me explain...

The Problem

I have a call to a function which initializes an XMLHttp request object based on the browser, of course, grabs some form inputs, and sends those values in the request header of a call to my nifty php function, which manipulates these inputs and gives me some XML in return. Pretty standard stuff. After using this for a while, I noted that it seemed to fail in IE, but not in Firefox (surprise). After some debugging I had determined that IE was indeed making the request, and was indeed getting back data, but the data was all invalid. I tried calling my php file directly from IE, with the same parameters that my javascript pulls, and got legitimate results. What was going on!?

Clearly, the php file seemed to not be getting the right parameters, even though the javascript was computing them correctly. Here is the code:


function customTime() {

// Get form element values
param1 = document.getElementById('param1').value;
...

// Initialize the XMLHttpRequest object
var xmlHttp = ajaxInit();

if (xmlHttp) {

// Define what to do when data is ready
xmlHttp.onreadystatechange=function() {
if(xmlHttp.readyState == 4) {

// Note that even though I get bogus data,
// I still get data... confusing!
var xmlDoc = xmlHttp.responseXML.documentElement;
var nmarkers = xmlDoc.getElementsByTagName("marker");

alert('Number of results: ' + nmarkers.length +
'\nSome data: ' + nmarkers[0].getAttribute("number"));

}
};

// Send the request...
try {
xmlHttp.open("POST", 'custom_data.php', true);
xmlHttp.setRequestHeader('Content-Type', "text/xml");
xmlHttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");

xmlHttp.send('param1=' + param1 + ...);

} catch (e) {
alert("Unable to make request, please try later... Error:"
+ e.message);
}
}
}


The 'Solution'

The problem, in fact, was that, for some reason, using the parameter of XMLHttp.send() to add my form inputs to the request header of my http request failed in IE. The reason for this still has me scratching my head, but the fix was simple enough:


// Send the request...
try {
xmlHttp.open("POST", 'custom_data.php?param1='
+param1+ ..., true);
xmlHttp.setRequestHeader('Content-Type', "text/xml");
xmlHttp.setRequestHeader("Content-Type",
"application/x-www-form-urlencoded; charset=UTF-8");

xmlHttp.send(null);

} catch (e) {
alert("Unable to make request, please try later... Error:"
+ e.message);
}


All I did was move the parameters as part of the URL for the XMLHttp.open() function. Tada! I'll try to do some research into the open and send functions and post the method behind the madness when I get a chance.

No comments: