VMX
VMX

Reputation: 307

Ajax script only works when the received XML is big enough/takes long enough to load?

I have a jQuery script that calls a PHP file that will query a database, then spit the results as XML. The jQuery script takes the XML, parses it and puts it inside an array to draw some charts.

This is the Ajax script:

<script>

var arr={};    

$(document).ready(function(){

  $.ajax({
    type: "POST",
    url: "http://myserver.com/query.php",
    dataType: "xml",
    success: function(xml) {
        $(xml).find('item').each(function(index,value){
            var data={};
            $(this).find('*').each(function(i,v){
                if(isNaN(parseFloat($(this).text()))) {
                    data[$(this).prop('tagName')]=$(this).text();
                } else {
                    data[$(this).prop('tagName')]=parseFloat($(this).text());
                }
            });
            arr[index]=data;
        })
        DataLoaded();
    }
  });
});

</script>

I've tested this script using a real query inside the query.php file, and it works fine. Data is retrieved from the DB, shaped into XML format and sent back to JavaScript, where it's correctly processed and played with.

Now... I've found the weirdest of problems when modifying the query: the ajax script doesn't work if the returned XML is too short??

A (simplified) example of the XML output that works fine with the Ajax script:

<results>
 <item>
  <variable1>value1</variable1>
  <variable2>value2</variable2>
  <variable3>value3</variable3>
 </item>
 <item>
  <variable1>value4</variable1>
  <variable2>value5</variable2>
  <variable3>value6</variable3>
 </item>
 <item>
  <variable1>value7</variable1>
  <variable2>value8</variable2>
  <variable3>value9</variable3>
 </item>
 <item>
  <variable1>value10</variable1>
  <variable2>value11</variable2>
  <variable3>value12</variable3>
 </item>
</results>

An example of the XML output that doesn't work:

<results>
 <item>
  <variable1>value1</variable1>
  <variable2>value2</variable2>
  <variable3>value3</variable3>
 </item>
 <item>
  <variable1>value4</variable1>
  <variable2>value5</variable2>
  <variable3>value6</variable3>
 </item>
</results>

For the last case, the PHP is working fine (I can access the PHP file directly from the browser and I see the XML output as shown above), but if I run the HTML file on the server, it'll simply stall forever without ever showing the data.

I've used Chrome debugging tools and Fiddler, and I've seen that my server is apparently returning a "500 Internal Server Errror". But, if I inspect the message in Fiddler, the correct XML output is actually there?!?!

Why is the server returning a 500 Internal Server Error together with the XML data?? And why is it throwing the error ONLY when the output is too short??

I mean, I could understand it having problems with longer datasets... but with shorter ones??

I'm completely at a loss here... any help would be really appreciated!

Edit: Some more info from Fiddler.

The ONLY difference between the response messages seems to be in the header.

Successful case:

HTTP/1.1 200 OK
Date: Mon, 07 Oct 2013 21:50:10 GMT
Server: Apache/2.2.12 (Linux/SUSE)
X-Powered-By: PHP/5.2.14
Content-Length: 4627
Keep-Alive: timeout=15, max=99
Connection: Keep-Alive
Content-Type: text/xml

Failure case:

HTTP/1.0 500 Internal Server Error
Date: Mon, 07 Oct 2013 21:21:22 GMT
Server: Apache/2.2.12 (Linux/SUSE)
X-Powered-By: PHP/5.2.14
Content-Length: 371
Connection: close
Content-Type: text/xml

Below this, both messages contain just the clean XML data as expected!

Update:

PHP code:

<?php

$dbhost = 'myserver.com';
$dbuser = 'login';
$dbpass = 'password';
$dbname = 'DB';


$link = mysql_connect($dbhost, $dbuser, $dbpass) or die("MySQL Error"); 
mysql_select_db($dbname, $link) or die("DB error");


$sql = "select bla bla bla... working query here";

$result = mysql_query($sql);

function mysql_XML($result, $docName='results', $itemName='item') {
   $field = array();

   for ($i=0; $i<mysql_num_fields($result); $i++)
      $field[$i] = mysql_field_name($result, $i);

   // XML document
   $dom = new DOMDocument('1.0', 'UTF-8');
   $doc = $dom->appendChild($dom->createElement($docName));

   for ($i=0; $i<mysql_num_rows($result); $i++) {

      $node = $doc->appendChild($dom->createElement($itemName));

      for ($b=0; $b<count($field); $b++) {
         $textField = $node->appendChild($dom->createElement($field[$b]));
         $textField->appendChild($dom->createTextNode(mysql_result($result, $i, $b)));
      }
   }

   // returning XML as text
   $dom->formatOutput = true; 
   return $dom->saveXML();    
}

header ('Content-type: text/xml');
echo mysql_XML($result);

$mysql_close();

?>

Upvotes: 3

Views: 195

Answers (2)

VMX
VMX

Reputation: 307

Thanks to n.st suggestion, I found the problem!

I looked in the server logs and I found there was a specific line in the PHP script that was throwing an error... one line that read:

$mysqli->close();

This line was supposed to be commented out (since in the end I resorted to using the deprecated 'mysql_' functions), but I had left it uncommented for some reason.

Anyway... even though it was a PHP error, the PHP itself didn't throw any errors when accessed directly from the browser. And furthermore, this was only causing the '500 Internal Server Error' response when the query was short enough (short enough being, maybe, 10 seconds long to run), while for queries longer than that I was seeing no errors in the browser!

Maybe for longer queries, the 500 error was somewhat "expired" by the time the actual XML arrived?? I really have no idea... but if any of you face a 500 error, remember: check for ANY errors in your PHP code! Even non-errors in the browser can become errors in the AJAX transaction.

Thanks to all!

Upvotes: 1

codyThompson
codyThompson

Reputation: 95

It's possible that an entry in your database contains characters that DOMDocument doesn't like &rsquo; for example. It's been a while since I've used the php XML libraries but I'm pretty sure they will throw an error when you try to use a HTML special character not defined by XML. Check your database for instances of html special characters. Something like select * from some_table where some_column like '%&%;'; should return possible html special characters.

A special character being found in a row 'farther down' in the table you query against would explain why 'shorter' responses work when 'longer' responses don't.

Upvotes: 0

Related Questions