Solved

IE - Ajax problem - Data necessary to complete this operation is not yet available

Posted on 2010-09-10
9
2,160 Views
Last Modified: 2013-12-08
Hi Experts, I'm trying to make a call to ajax which it supposes to return the percentage left while waiting for the file to finish generating info. Everything works fine in Firefox but in IE it generates an error as stated in the topic. It does work in IE but with an error. Below is the javascript I used. If I were to comment out the line after  "ajaxRequest.readyState == 3" (line #37)  it seems to work without any error.
/*---------------------------------------------------------

----------------------------------------------------------*/
function generateCompleteExport(data){
	ajaxRequest = GetXmlHttpObject(); 
	ajaxRequest.async = false;
	if (ajaxRequest==null){
		alert ("Browser does not support HTTP Request")
		return
	} 
	
	var loadingImg = '<img src="/reports/assets/scripts/loading.gif" title="Loading...">';
	document.getElementById('status').innerHTML = loadingImg;
	
	// Add parameter 'q' to URL
	var url = 'completeExportGenerate.php?'+data;	
	// Adds a random number to prevent the server from using a cached file
	url=url+"&sid="+Math.random();	
	
	var numTest =0;
	var response;
	var index;
	
	ajaxRequest.onreadystatechange = function(){
		if(ajaxRequest.readyState == 4){
			if(ajaxRequest.status == 200) {
				response = ajaxRequest.responseText.split("###");
				index = response.length-1;
			
				document.getElementById('status').innerHTML =response[index];
			} else {
				//window.status = "No Update for " + targetId;
				document.getElementById('status').innerHTML="Error code " + ajaxRequest.status;
			}
		}
		if(ajaxRequest.readyState == 3){
			response = ajaxRequest.responseText;.split("###");
			if( (response.length-2)<= 0)
				index = 0;
			else
				index = response.length -2;
				
			document.getElementById('status').innerHTML =loadingImg+'<br>'+response[index];
		}
	}
	ajaxRequest.open("GET", url, true);
	ajaxRequest.send(null);
}

Open in new window

0
Comment
Question by:infernothao
  • 5
  • 2
  • 2
9 Comments
 
LVL 40

Expert Comment

by:gurvinder372
ID: 33650610
did you tried removing lines 36-44 and check?
0
 
LVL 6

Expert Comment

by:apresence
ID: 33650691
There is a typo on line 37:
response = ajaxRequest.responseText;.split("###");

It should be:
response = ajaxRequest.responseText.split("###");

About the ready states, you can find more info here:
http://www.devx.com/webdev/Article/33024/0/page/2

State 3 means the page is still loading, so the data is not going to be ready for you yet.
0
 

Author Comment

by:infernothao
ID: 33651475
Thanks for answering guys. I'm pretty new to ajax...  anyway, I'm not totally sure what readyState == 3  do but I read some where it says something about interacting between the client and the server. The reason I need line 36-44 is because I want to update the progress bar percent while the file is being generated in the background. Hmm... when I changed the "responseText" to "responseXml" it seems to stop the error. I have tried using responseXml before but I have no clue how to send data back using Php.
0
 

Author Comment

by:infernothao
ID: 33651480
@apresence, fixed that typo but still error.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 
LVL 40

Expert Comment

by:gurvinder372
ID: 33652917
<<I'm not totally sure what readyState == 3  do but I read some where it says something about interacting between the client and the server>>
Not required to handle in most cases.
You can read about it here
http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp

In case you want to indicate the user that response is being processed at the background, then you can update those lines to

if(ajaxRequest.readyState == 3){
                  document.getElementById('status').innerHTML ="Response is fetched, loading...";
            }
0
 

Author Comment

by:infernothao
ID: 33654839
Well, the thing is it will take anywhere between 5-30 minutes. It would be nice to know how long it will take.
0
 
LVL 6

Accepted Solution

by:
apresence earned 500 total points
ID: 33655541

Here's an official document from Microsoft on the issue.  Looks like they have something new in IE8 called XDomainRequest that might work, but there are some obstacles.  Check here:
http://blogs.msdn.com/b/ieinternals/archive/2010/04/06/comet-streaming-in-internet-explorer-with-xmlhttprequest-and-xdomainrequest.aspx

None the less, being the stubborn person who never accepts "no" for an answer, I did the research myself.  From Microsoft's documentation:
You cannot call responseBody and responseText properties to obtain partial results (readyState = 3). Doing so will return an error, because the response is not fully received. You must wait until all data has been received.
In comparison, the Microsoft XML (MSXML) version of the IXMLHTTPRequest interface exposes partial results through the responseStream property, which the Windows Internet Explorer native version does not implement.
Reference: http://msdn.microsoft.com/en-us/library/ms534361(v=VS.85).aspx
Assuming we want to explore other Microsoft objects that might allow us to get partial results, a very high level, we'd still need to avoid getting the error message.  To do this, replace line 37 with the following:
try {
  response = ajaxRequest.responseText.split("###");
}
catch (e) {
  response = '';
}
Now, in an attempt to get back some partial results, I've tried several different Microsoft objects that support XML/HTTP requests and getting partial results either in responseText or responseStream, and none of them have worked.

So, there are a couple of alternatives you might explore:
1. If your PHP script is doing some sort of iterative process and produces data in blocks along the way, you could send an XML request for each block of data, avoiding the partial results issue.  This would be especially useful if you know how many blocks of data you would send in advance, because then you can send this information to the client side at the beginning and implement a progress bar as the data is downloaded.  Of course, if your PHP script does some work and spits all the data out at once, then there's no way you're going to be able to do any sort of reliable progress indicator.  To test this, try calling your PHP code from a command prompt on the host system.
2. You could set up a timer event that fires every 5 seconds or however long you'd like to update some "Loading ..." text or graphic to indicate that the processing has not yet completed.  You don't really know how long it will take in this case, however.
3. Try ou thte XDomainRequest object mentioned above.  This has the drawback of not being compatible with browsers prior to IE8, and the 2kb buffering issue mentioned in the linked article.

I wrote a sample PHP script to generate 10 blocks of data every second for testing purposes (attached).  Please note a few things in the code:
1. The disable_browser_cache() function disables the browser cache on the PHP side, so you don't have to pass in a random number on the JavaScript side like you are currently doing.
2. After each line/block of data, I'm calling ob_flush() to cause PHP to flush it's output buffer.  If IE was able to picking up partial data, this is how we'd ensure IE always gets each block of data right away.  Otherwise, there's an internal buffer where the data would be stored until some threshold is met, and only at this point would anything be sent over the network to your JavaScript code.
3. Is there any reason you are using "###" as a delimiter instead of something more standard like "\n"?
I ran the PHP script on the server side and confirmed that it writes out each block of data every second, however on the JavaScript side I only get the whole block of data and never any partial data.

<?php

  // Disables the browser cache.  MUST be called before any data is written out

  function disable_browser_cache()

  {

    header("Expires: Mon, 01 Jan 2001 00:00:00 GMT");

    header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");

    header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");

    header("Cache-Control: post-check=0, pre-check=0", false);

    header("Pragma: no-cache");

  }



  // Disable browser cache

  disable_browser_cache();



  // Write out some data

  for ($i=0; $i<10; $i++)

  {

    echo "Data line $i###";

    ob_flush();

    sleep(1);

  }

?>

Open in new window

0
 

Author Closing Comment

by:infernothao
ID: 33665987
Thanks for the advises.
0
 

Author Comment

by:infernothao
ID: 33666028
Guess I'm so focus on one think that I couldn't think straight. Thanks for Apresence for not giving up on me and give me something to work on. The solution I came up with is  somewhat a combination of what Apresence's advises. Every 5 seconds or so I'll load and read a XML file generated by PHP. Thanks.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

#Citrix #Internet Explorer #Enterprise Mode #IE 11 #IE 8
JavaScript can be used in a browser to change parts of a webpage dynamically. It begins with the following pattern: If condition W is true, do thing X to target Y after event Z. Below are some tips and tricks to help you get started with JavaScript …
Google currently has a new report that is in beta and coming soon to Webmaster Tool accounts. This Micro Tutorial will highlight new features for Google Webmaster Tools.
Shows how to create a shortcut to site-search Experts Exchange using Google in the Chrome browser. This eliminates the need to type out site:experts-exchange.com whenever you want to search the site. Launch the Search Engine Menu: In chrome, via you…

759 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now