AJAX problem: responseText inexplicably returns empty

I decided to finally make the plunge and teach myself AJAX - after getting one app to work, I copied and pasted my code (more or less) into a new app to tinker with it more and turn it into something useful, and it stopped working. I spent around 5 hours trying to trace exactly what the issue was, and that I hadn’t made some sort of stupid typo.

Essentially, in one .js file with my AJAX event handlers, responseText returns blank. That would seem to point to a problem with the file I’m sending my data to on the server side, but when I use a file that I know works, it still returns blank.

Code:
ajaxauth.js:

function createRequestObject(){
	http_request = false;
      if (window.XMLHttpRequest) { // Mozilla, Safari,...
         http_request = new XMLHttpRequest();
         if (http_request.overrideMimeType) {
            http_request.overrideMimeType('text/xml');
         }
      } else if (window.ActiveXObject) { // IE
         try {
            http_request = new ActiveXObject("Msxml2.XMLHTTP");
         } catch (e) {
            try {
               http_request = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
         }
      }
      if (!http_request) {
         alert('Cannot create XMLHTTP instance');
         return false;
      }
      return http_request;
}

var http_request = createRequestObject()

function sendPass(formpass){
	document.getElementById('autho').innerHTML = 'Verifying...';
	var password = 'pass=' + formpass;
	http_request.open('POST','ajaxauth.php', true);
	http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	http_request.onreadystatechange = checkAuth;
 	http_request.send(password);
}

function checkAuth(){
if (http_request.readyState == 4) {
            result = http_request.responseText;
            document.getElementById('autho').innerHTML = result;
         }
}

ajaxauth.php:

<?php

require './auth.dat'; //should NOT be in the /var/www tree in production!

if ($_POST['pass']==$protempass){ echo 'Authenticated as Pro-Tem! Close this window when you are done!<input type=hidden value='.$_POST['pass'].' name=pass>';}
elseif ($_POST['pass']==$adminpass){echo 'Authenticated as Admin!  Close this window when you are done!<input type=hidden value='.$_POST['pass'].' name=pass>';}
else{echo '<form name="authorization" onSubmit="sendPass(authorization.pass.value)" method="POST"><input type="password" name="pass" size="32"><input type="submit" value="Authenticate"> Authentication failed!<br />';}

?>

These two blocks of code work great.

The next file does not.

editdb.js:

var http_editdb = createRequestObject()

function newSenator(){
	var newsen = 'lastname=' + document.newsenator.lastname.value + '&firstname=' + document.newsenator.firstname.value + '&middleinitial=' + document.newsenator.middleinitial.value + '&year=' + document.newsenator.year.value + '&newsenator=1' + '&pass=' + document.authorization.pass.value;
	document.getElementById('senators').innerHTML = document.getElementById('senators').innerHTML + 'Adding...<br />';
	http_editdb.open('POST','ajaxauth.php', true);
	http_editdb.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	http_editdb.onreadystatechange = updateTable;
 	http_editdb.send(newsen);
}

function updateTable(){
if (http_editdb.readyState == 4) {
            result = http_editdb.responseText;
            document.getElementById('senators').innerHTML = result;
         }
}

This code above typically points to a file called “ajaxeditdb.php”, but in this case I’m pointing the newSenator function at “ajaxauth.php” because I know that ajaxauth should return SOMETHING in responseText. I’ve stepped through and echoed every variable out of the javascript file with alert(); and it opens the function updateTable() and the readyState gets to 4 and everything seems peachy, but then the responseText is blank. My best guess is I’m missing something about the way I’m sending data with newSenator(), but I really can’t see how that would be the case.

Yes, the code is sloppy/nicked from various AJAX tutorials, and no, I don’t think I need to open a second XMLhttp object if these are both in the same page, but I’m pretty sure that those are unrelated to the problem. Anyone have any ideas to help track down what the issue is? Thanks in advance to anyone who takes the time to help me out.

These two blocks of code work great.

These statements do not belong in the same script:

var http_request = createRequestObject();
...
function createRequestObject()
{
   http_request = false;
   ...
   return http_request;
}

You also need to perform some more checks here:

if (http_editdb.readyState == 4)

You never call sendPass() in either script, so neither of them work.

There is no createRequestObject() function in your second script.

readyState = 4 - the response is complete. But was it successful? Adding this alert may provide some clues.

function updateTable(){
if (http_editdb.readyState == 4) {
alert(http_editdb.status);
            result = http_editdb.responseText;
            document.getElementById('senators').innerHTML = result;
         }
}

7stud: I don’t see why they shouldn’t be in the same script?

sendPass() is called from the PHP page with the following code:

<div id="autho">
<form name="authorization" onSubmit="sendPass(authorization.pass.value)" method="POST">
<input type="password" name="pass" size="32"><input type="submit" value="Authenticate"><br />
</div>

newSenator is called in a similar way. The sendPass() function most certainly works, so I’m quite sure that’s not an issue.

Both of these scripts are run from the same page, so the second createRequestObject() call is referencing the function definition in the first script.

What additional checks do I need to perform?

Mittineague: The alert isn’t returning any status - it pops up blank. It should be 200, yes? What could cause a blank status?

Odd indeed. Blank responseText and blank status. Seems you should at least be getting some status, either successful or otherwise. Sorry, but I really don’t see what’s wrong that would cause this.

I moticed a “bug” report dealing with
overrideMimeType(‘text/xml’)

Also. although your script isn’t using responseXML, it seems that unless the server returms an text/xml header, the responseXML will be null. http://www.xulplanet.com/references/objref/XMLHttpRequest.html (user note#2)

mjohnson at pitsco dot com February 23, 2006, 8:25 am
FYI, the server must be sending an XML Content-Type (text/xml works, but text/html does not) for responseXML to return anything except null. Just spent two hours on that one.

Michael

http://www.oreillynet.com/cs/user/view/cs_msg/72422

Using http_request.overrideMimeType(‘text/xml’); when you’re not actually fetching XML is incorrect, and will cause confusing Javascript Console errors in the latest versions of Firefox. The XMLHttpRequest object will try and parse the fetched file as XML, and complain when it can’t.

So I’m not sure if this has anything to do with this problem, but maybe if you used a header(‘Content-type: text/xml’) in your PHP file it might work.

Changing the header didn’t change anything. I did notice, however, that IE absolutely refuses to work as firefox does with the scripts - even the HTML that these scripts are on isn’t rendering the same, when I checked to see if it was a Firefox/Mozilla-related problem. If no clear solution is forthcoming, I’m strongly tempted to scrap the AJAX for this project, since it isn’t needed (and more intended to be a learning experience for me than anything else) and try again later. Thank you for the help, though… but this is the first time I’ve used more than extremely simple javascript, so even thinking to look for what you looked for was way over my head.

One thing to note though is that http_editdb.status is null along with responseText, so I don’t think it could be related to that responseXML issue that you brought up. Again, my best guess is that it’s some obscure issue with the way I’m sending multiple arguments to ajaxauth.php, but I’m out of time today at 5am PST to tinker more with this part of the project.

Mutiple requests? Sorry, I didn’t see that in your posts. Ajax does seem to have bugs that all the hype seems to have missed mentioning. In another thread here in the forums there was a problem with ajax returning " ^" after each result, in another images won’t load in IE. Both as of yet unresolved.
I did notice in my reading somewhere that someone had problems with multiple requests and had to use a settimeout to give each request 10 seconds to complete before calling the next.
Learning experience? Well it certainly has been that. Maybe if you get some time later you can come back to this and try it again.

EDIT:
The image load problem was solved. It was not an AJAX problem, but caused by a script conflict.

Multiple arguments, not requests, as in I’m doing http_editdb.send(‘arg1=val1&arg2=val2&arg3=val3’); versus http_editdb.send(‘arg=val’);, which is really the only substantive difference between the working code and the non-working code that I can see. I am also doing multiple requests on the same page, but they’re going to different .php files, they’re at different times (one finishes before the other starts), and they use different XMLhttp objects, so I can’t imagine that’s related. Thanks again!

Trying to debug imaginary code is never very productive. As soon as you are ready to provide a simple, complete example that demonstrates your problem, you may have more luck getting some relevant help.

If you’ve abandoned the script for now it’s moot anyway, but,
If the script works with
http_editdb.send(‘arg=val’);
but not with
http_editdb.send(‘arg1=val1&arg2=val2&arg3=val3’);
Then I would be interested to know what the variable newsen looks like
Seeing the mark-up for the form these values come from might help.

function newSenator(){
	var newsen =
 'lastname=' + document.newsenator.lastname.value +
 '&firstname=' + document.newsenator.firstname.value +
 '&middleinitial=' + document.newsenator.middleinitial.value +
 '&year=' + document.newsenator.year.value +
 '&newsenator=1' +
 '&pass=' + document.authorization.pass.value;

	document.getElementById('senators').innerHTML = document.getElementById('senators').innerHTML + 'Adding...<br />';
	http_editdb.open('POST','ajaxauth.php', true);
	http_editdb.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	http_editdb.onreadystatechange = updateTable;
 	http_editdb.send(newsen);
}

But if that was a problem shouldn’t the status be 400 - bad request, not null ?

7stud: I thought that I had provided such:

This code works.


function sendPass(formpass){
	var password = 'pass=' + formpass;
	http_request.open('POST','ajaxauth.php', true);
	http_request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	http_request.onreadystatechange = checkAuth;
 	http_request.send(password);
}

function checkAuth(){
if (http_request.readyState == 4) {
            result = http_request.responseText;
            document.getElementById('autho').innerHTML = result;
         }
}

This code does not.

function newSenator(){
	var newsen = 'lastname=' + document.newsenator.lastname.value +
 '&firstname=' + document.newsenator.firstname.value +
 '&middleinitial=' + document.newsenator.middleinitial.value +
 '&year=' + document.newsenator.year.value +
 '&newsenator=1' +
 '&pass=' + document.authorization.pass.value;
	http_editdb.open('POST','ajaxauth.php', true);
	http_editdb.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	http_editdb.onreadystatechange = updateTable;
 	http_editdb.send(newsen);
}

function updateTable(){
if (http_editdb.readyState == 4) {
            result = http_editdb.responseText;
            document.getElementById('senators').innerHTML = result;
         }
}

The code is essentially the exact same sans variable names, except the latter results in a null http_editdb.readyState and .status, while the former works. http_editdb and http_request are different XMLhttp objects.

Mittineague: alert(newsen); gives me this: “lastname=Smith&firstname=John&middleinitial=T&year=2006&newsenator=1&pass=password”

The form is:

<form name="newsenator">
<tr>
<td><input type="text" name="lastname" value="Last Name" size=30 onClick="clearText(this)">, <input type="text" name="firstname" value="First Name" size=20 onClick="clearText(this)"> <input type="text" name="middleinitial" size=1 value="X" onClick="clearText(this)"></td>
<td><input type="text" name="year" value="YYYY" size="4" onClick="clearText(this)"></td>
<td>Active</td>
<td><a href="" onClick="newSenator()">Submit new senator?</a></td>
</tr>
</table>
</form>

The <td> and <tr> tags coming from the fact that this is in the last row of a table of ‘SELECT * FROM senators;’ data.

I’ll keep working on it til I’m sure I can’t get it to work, but for learning, since I’m not convinced this will be resolved. If it would be useful, I can make a limited FTP account on my hosting server and just make it so people can go in and read every single line of code that’s in the project so far so you can poke through the guts and see what is doing what - but I’m pretty sure that everything that’s relevant to the issue at hand I’ve posted.

7stud: I thought that I had provided such:

This code works.
You consider that a complete working example? I hate to inform you of this, but your code is just a couple of functions you defined. Nothing calls those functions, so your code doesn’t ‘work’ at all.

I suggest you read some more tutorials on xmlhttp requests. If you aren’t able to understand the tutorials, then I suggest you stick to more basic scripts until you gain more experience.

I think 7stud may have hit on something a few posts back.
This works

var http_request = createRequestObject()
......
      return http_request;
......
 	http_request.send(password);

but this doesn’t

var http_editdb = createRequestObject()
......
      return http_request;
......
 	http_editdb.send(newsen);

I’m kinda new to OOP, but in the few PHP scripts I’ve experimented with, I have accessed the objects returned property value like
< $object_name->returned_value_name > eg.
http_editdb->http_request
Although that wouldn’t explain why you wouldn’t have to likewise use
http_request->http_request in the working script.
I don’t know that much about PHP OOP let alone javascript OOP, but I bet the problem is something to do with this.
AFAIK the javascript syntax is < object_name.returned_value_name >
Maybe if you try an alert in the newSenator() function it can give some clues.

alert("http_editdb: " + http_editdb + "http_request: " + http_request + "http_editdb.http_request: " + http_editdb.http_request);