Ajax .onreadystatechange not working (mac)

Help! After 24 hours of trying everything, I know a lot more, but the problem persists. Using a simple test program I’ve narrowed down to the fact that with Firefox 3.5.3 and Safari, both on Mac, my xmlHttpRequest works, but only in synchronous mode. If I enable the .onreadystatechange listener, then the callback function seems to catch readyState = 1 and not to run again after that, even though when I disable it (again in synchronous only) readyState moves to 4 and I get the desired responseText.

Why can’t I use asynchronous, and why doesn’t onreadystatechange work?

Thanks! Hope someone can help.

Here is my simplified, but working code:

<html>
<head>
<script type=“text/javascript”>

function myAjax(url)
{
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject(“Microsoft.XMLHTTP”);
}

xmlhttp.open(“GET”,url,false); // Works only with synchronous httpRequest.

//xmlhttp.onreadystatechange = listener(); // Listener disabled…
// Doesn’t seem to get called after the first time, when readyState = 1.

xmlhttp.send(null);

// Posting response from server on html page.
document.getElementById(‘alpha’).innerHTML=xmlhttp.responseText;

document.getElementById(‘beta’).innerHTML=xmlhttp.readyState;
// readyState = 4 as long as onreadystatechange is disabled and synchronous.
}

// Would be called if onreadystatechange enabled, but is not called here.
function listener(){
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
alert (‘success’);
}
else {
alert (‘another failure’);
} }
</script>

</head>
<body>
<div id=“alpha”>
<p>Line to show server response</p>
</div>
<div id=“beta”>
<p>Line to show readyState</p>
</div>
<button type=“button” onclick=“myAjax(‘serverscript.php’)”>Click php</button>
<button type=“button” onclick=“myAjax(‘xmltext.txt’)”>Click xml</button>
</body>

<!-- **** This is the server side script in the file “serverscript.php”****
<?php
echo ‘This text comes form a php server script.’;
?>
–>
</html>

Don’t try to read responseText before the readystate has progressed to 4. It’s considered an error in some browsers.

Thanks, that’s a good thought. I tried removing any call to responseText until the listener function hits 4. The result is that each button push that calls the myAjax function leads to only one listener call and gets a “1” readyState. After that, nothing. We never get to 4, synchronous or asynch. Same for Safari and for Firefox (with & without firebug running) Firebug shows length of calls to server (150 ms. ) so I think that means firebug is following the response from the server, even though Ajax isn’t showing it.

Here is the code I changed:

xmlhttp.open("GET",url,true);  
xmlhttp.onreadystatechange = listener();  // Listener enabled...
xmlhttp.send(null);

}

function listener(){
changingnumber = parseInt(Math.random()*99);
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
document.getElementById(‘alpha’).innerHTML=xmlhttp.responseText+ ’ is from server’;
}
else {
document.getElementById(‘beta’).innerHTML=xmlhttp.readyState+’ '+changingnumber;
// (changing number shows each new listener call.)
} }

Oh, I didn’t notice this when it was commented out.


xmlhttp.onreadystatechange = listener();

When you use parenthesis like listener(), you call the function. This ends up assigning the return value of your function to the onreadystatechange property. You want to assign the actual function to the property, because the function will be later called for you automatically.


xmlhttp.onreadystatechange = listener;

Thanks so much. When I rewrote the .onreadystatechange = listener; without parentheses it worked. I’ll go back and try to understand better exactly how that works, but in the meantime you seem to have solved my problem. I am very grateful after so many hours of trying everything.

Yours, JS