Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

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

Posted on 2010-09-10
9
2,212 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
Networking for the Cloud Era

Join Microsoft and Riverbed for a discussion and demonstration of enhancements to SteelConnect:
-One-click orchestration and cloud connectivity in Azure environments
-Tight integration of SD-WAN and WAN optimization capabilities
-Scalability and resiliency equal to a data center

 

Author Comment

by:infernothao
ID: 33651480
@apresence, fixed that typo but still error.
0
 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I found this questions asking how to do this in many different forums, so I will describe here how to implement a solution using PHP and AJAX. The logical flow for the problem should be: Write an event handler for the first drop down box to get …
This article offers some helpful and general tips for safe browsing and online shopping. It offers simple and manageable procedures that help to ensure the safety of one's personal information and the security of any devices.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
This Micro Tutorial will demonstrate how nuggets on the Web are formatted by using Chrome Developer Tools. These tools would not only view the site's CSS but it can also modify it and save the CSS to use on your own site.

856 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