PDA

View Full Version : readyState 3 question


rfresh
04-29-2009, 07:47 AM
In my ajax code snippet below I am returning to my main form the line number of a file I am processing on the server in my ajax script. This may not be an ajax issue but I am not sure.

What is happening, is the the id_meter_label object is filling with "123456789" from a 9 line file on the server - so ajax readyState 3 is working to bring back the intermediate results - 9 times - each one the proper line number value.

I *thought* the id_meter_label object would just display 1 thru 9 and over write each digit in place. But instead it strings out each value after the preceeding one so it ends up looking like this: 123456789

Ajax question: is 'response' holding the previous value each time it returns? or am I not creating the id_meter_label correctly? I have it in a span tag.

I'm trying to make sort of a progress meter on my main form to display which line number of the file (selected by me) is being processed on the server.

Thanks...


if (http.readyState == 3)
{
var response = http.responseText;
document.getElementById("id_meter_label").innerHTML = response;
}

bdl
04-29-2009, 09:22 AM
Hmm. What browser are you working with? MSDN's XMLHttpRequest specification claims that during readyState 3, responseText isn't available. In FF 3.0.x for Linux, my tests show the exact same result you do, that 12345 is returned. I took it one step further and created a case for each readyState:

<html>
<head>
<title>readyState test</title>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
</head>
<body>
<div id="results"></div>
<div id="container">
<button id="requestBtn" name="requestBtn">Initialize Request</button>

</div>
<script type="text/javascript">
function doRequest() {
var counter=1;
var xhr= (window.XMLHttpRequest) ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
var url= 'send12345.php';
var resultsDiv= document.getElementById("results");
xhr.open("GET",url,true);
xhr.onreadystatechange= function(evt) {
if ( xhr ) {
switch( xhr.readyState ) {
case 1:
resultsDiv.innerHTML+='<p>XHR making connection...</p>';
break;
case 2:
resultsDiv.innerHTML+='<p>XHR sending any data...</p>';
break;
case 3:
resultsDiv.innerHTML+='<p>Iteration: ['+counter+'] '+xhr.responseText+'</p>';
counter++;
break;
case 4:
resultsDiv.innerHTML+='<p>XHR request complete: '+xhr.responseText+'</p>';
break;
}
}
};
xhr.send(null);
}

document.getElementById("requestBtn").onclick= doRequest;
</script>
</body>
</html>

(tested but only on FF for Linux)

PHP script just uses 5 echo statements with 1..5.

What I'm thinking based on the results is that readyState 3 doesn't actually contain anything, but at the very last split second the responseText property is available and it dumps it out. I even attempted to put a sleep() call in the PHP script and it waited for 5 seconds before doing anything, then dumped the readyState 2, 3 and 4 functions.

Here's the PHP script for completeness:

<?php
// send12345.php
foreach( range(1,5) AS $n ) {
echo $n;
}
?>

rfresh
04-29-2009, 01:53 PM
I'm using the latest ver of FF. Yes readyState 3 only fires with FF and Windows Safari. Hmmm you might be right in that it's all displaying at once when readyStatec3 is finished. I'm going to set an internal JS var and see how many times it is actually coming back from the server.

Thanks

Dave&Jenni
10-24-2009, 05:54 PM
Since this was exactly the question I had but I couldn't find an answer to it anywhere obvious, I thought I'd post what I found here. Even though this thread is a bit dead..

I think the problem is more to do with PHP than JavaScript. The readyStates increment from 1 when the request starts to receive stuff from the server. PHP buffers the script before sending it back to the browser where the JavaScript can start to use it. This means PHP will wait, do the whole script (including any sleep(5)ing), then send it in full. When the PHP result is quite small (i.e. small enough to load all at once), you get readyStates 2 3 4 all at once.

I did some tests with ob_flush() (http://php.net/manual/en/function.flush.php) to force PHP to send what it had to that point to the browser and then the 2s and 3s started kicking in accordingly, in advance of the 4.

I did try flush() but on my server (just localhost, at the moment) it didn't do anything. Different things will probably work on different servers.

Safe.


_