Hi All, I need the help of a real expert because I'm still having difficulty with this Ajax technique. I have posted before about this on another site forum, but no replies (sigh). The script below works with FF only when the alert is in the code, and doesn't work at all in IE. Of the numerous posts on the net about doing this, none seem to work at all. I believe that the IE portion of the problem has to do with the req.readyState or req.status, maybe. But in FF, why is the alert necessary for the req.readystatechange to work? Or, what else is the alert doing that I need to do? Something about clearing an error of trying to get a file header that doesn't exist? Oh, by the way, if I just go ahead and don't do anything at all, then it displays all of the existing links fine and just inserts 'X' for missing images when they don't exist, which is roughly 60% of the time, so that's not an acceptable approach, specially if the first several are the missing ones.

The html page is delivered from a php page at the end of a series of php login and verification pages, but I've tested this as a standalone - same thing. The image links are retrieved from an array, and there is absolutely no problem there - only in testing if the file exists so the array can be collapsed before going into the display routines. nB is declared as a global variable, btw. My code is this:

last part of main function call:
// collapse imagelink array removing missing elements //
for (m=imagetotl-1;m>=3;m--) {
	testExists(imagelink[m]); 
	alert("test");   //this statement that must be here to make it work! (What gives???) //          
	if(nB) {
		imagetotl--;
			for (n=m;n<=imagetotl+1;n++) {
				imagelink[n]=imagelink[n+1];
			}
	}
}
// Seed the starting image sequence //
document.pic.src=imagelink[0];
break;
}
}
}
}

function testExists(imagepath) {
    req = getreq();
    req.onreadystatechange = imagexists;
    req.open("head", imagepath, true);
    req.send(null);     
}

function imagexists() {
    if(req.readyState == 4) {
        if(req.status == 200)
        {
            // image exists
            nB=false;
        }
        else
        {
            // image doesn't exist
            nB=true;
        }
    }
}
 
function getreq() { // returns false if exists
	if(window.ActiveXObject) { // if IE
		try {
		return new ActiveXObject("Msxml2.XMLHTTP");
	} catch(e) {
		try {
		return new ActiveXObject("Microsoft.XMLHTTP");
		} catch(e) {
		return;
			}
		}
	} else if(window.XMLHttpRequest) { // if Mozilla, Safari, etc.
		return new XMLHttpRequest();
		}
}

Recommended Answers

All 5 Replies

For the sake of debugging, change this:
req.open("head", imagepath, true);

to this:
req.open("HEAD", imagepath, false);

I haven't done that (and I will tomorrow when I get to work), but I use firebug to look at the javascript and to see what is happening with the file finds - and in 42ms (ave) the 'not found' header is returned, the array collapses appropriately - HOWEVER, WITHOUT THE ALERT MESSAGE, the boolean is not evaluated correctly in function imagexists(), some problem with the readystatechange property, and I think (maybe) javascript is throwing some sort (unreported) error since the file header doesn't exist. So, the alert message is doing something that I need to do, only I don't know what it is doing behind the scenes.... Any ideas? I can't believe that I'm the only one who is trying to do this sort of thing. I just gotta take the ALERT message out. Getting it to work in IE is still an issue.

The real problem here is that you are calling the ajax request asynchronously. That's what the third parameter to req.open means.
true == asynchronous
false = synchronous

What that means is that when the script executes this:
req.send(null);

The javascript interpreter does not wait for the response. It continues executing your script.
Stop and think for a second. If the server takes 2 seconds to reply, but your javascript intepreter goes immediately to the next statement, then nB will not reflect the response from the server. That's why you need it to be synchronously. Basically, you are forcing the interpreter to pause until it gets a response.

The readystatechange and the readyState==4 are perfectly fine. To know if the error file does not exist you need to check for
req.status==404

200 means the files exists, but if it NOT 200, it does not necessarily mean it does not exist. For example
403 means you don't have permission to download the image/file, but it exists.

Also, ideally, your function imagexists() should return a value as shown below:

function imagexists(){
    if(req.readyState == 4) {
        if(req.status == 200)
        {
            // image exists
            nB=false;
        }
	   else if(req.status==404)
	   {// image doesn't exist
	       nB=true;
	   }
        else
        {
            // all other error codes will set this
            nB=null;
        }
retur nB;
    }
}

One last thing, if IE keeps giving you trouble, try
req.send('');

instead of req.send(null);

Many thanks, hielo, for your suggestion and clarification - you were exactly right about the synchronous (false) call. It now works perfectly.

But about the nb == null; well - there are only two possibilities in my case, file does/doesn't exist. If it exists then it can be retrieved.

I'm in debt to you for pointing this out to me.

>>there are only two possibilities in my case
This is OK, but you could rename:
function imagexists
to something more generic like:
function fileIsAvailable

and be able to reuse the function on other projects. 200 => true: Server is willing to give you the file. 404 => false: File truly does not exist.
anything else => null: You (the developer) need to look into this matter (Permission problem?, redirecting resource?,internal server error?)

Just a suggestion.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.