views:

644

answers:

2

I'm doing an AJAX fetch of a binary file the I am parsing in javascript. (Quake 2 BSPs, if anyone cares.) The code to fetch and parse the initial file is working fine, and looks roughly like this:

function loadFile(url) {
    var request = new XMLHttpRequest();

    request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200) {
            var parsed = parseFile(request.responseText);
        }
    };

    request.open('GET', url, true);
    request.overrideMimeType('text/plain; charset=x-user-defined');
    request.setRequestHeader('Content-Type', 'text/plain');
    request.send(null);
}

As I said, that works fine, and everything loads and parses correctly. However, the file also describes several secondary files (textures) that need to be retrieved as well, and so I've added an inner loop that should load and parse all of those files, like so:

function loadFile(url) {
    var request = new XMLHttpRequest();

    request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200) {
            var parsed = parseFile(request.responseText);
            for(var i = 0; i < parsed.files.length; ++i) {
                loadSecondaryFile(parsed.files[i].url); // Request code here is identical to this function
            }
        }
    };

    request.open('GET', url, true);
    request.overrideMimeType('text/plain; charset=x-user-defined');
    request.setRequestHeader('Content-Type', 'text/plain');
    request.send(null);
}

function loadSecondaryFile(url) {
    var request = new XMLHttpRequest();

    request.onreadystatechange = function () {
        if (request.readyState == 4 && request.status == 200) {
            var parsed = parseSecondaryFile(request.responseText);
        }
    };

    request.open('GET', url, true);
    request.overrideMimeType('text/plain; charset=x-user-defined');
    request.setRequestHeader('Content-Type', 'text/plain');
    request.send(null);
}

But every request made from within that loop immediately fails with the message (in Chrome, Dev Channel): NETWORK_ERR: XMLHttpRequest Exception 101 This strikes me as strange, since if I call loadSecondaryFile outside of loadFile it works perfectly.

My initial impression was that initiating an one ajax call in the onreadystatechage of another may be bad juju, but wrapping the secondary ajax calls in a setTimer doesn't make any difference.

Any ideas?

+2  A: 

And... SUCCESS! So I feel really stupid, and I realize now that there's no way anyone else could have given me a solution with the information I presented. Terribly sorry!

It has nothing to do with AJAX and everything to do with how I was getting my URLs. Recall that I mentioned I was loading binary data from a Quake2 bsp, in this case, texture paths. Textures in the bsp format are stored as fixed length 32 bit strings with null padding. I was reading them using substr like so:

var path = fileBuffer.substr(fileOffset, 32);

Which I thought was giving me a string like "e2u3/clip", but in reality was giving me "e2u3/clip\0\0\0\0..." Of course, when printed this would look correct (since console.log represents the null char as nothing.) but the browser recognized it immediately as a bad URL and tossed it out.

Changing my read code to:

var path = fileBuffer.substr(fileOffset, 32).replace(/\0+$/,'');

Gives me valid strings and fixes all of my apparent AJAX problems! sigh

Thanks for all the suggestions! It helped put me on the right track.

Toji
A: 

WHYYYYYYYYYYYYY????????? Why can't i use the function send(null)???

function getXmlDoc(httpReq, filename) { var xmlDoc;

httpReq.open("GET", filename, false /* sync */);
httpReq.send(null);
xmlDoc = httpReq.responseXML;
if (httpReq.status != 404 && httpReq.status!=403)
    return xmlDoc;
else
    return null;

}

In google Chrome and IE it gives me the error: Uncaught Error: NETWORK_ERR: XMLHttpRequest Exception 101

Can anyone help???

Marc
First off, since this isn't an answer to my questions you should post it as a new question instead of here. You'll get a better response that way. Secondly, yelling (ie: TYPING IN ALL CAAAAAPPPPSSS!) is annoying and will draw the ire of other users. Don't do it. Finally, I seem to remember hearing that synchronous ajax queries are subject to some interesting restrictions, so you may want to try it asynchronously and see if the problem goes away. If that's not it, make sure that the filename you are passing is a valid URL (no funny characters), which is what my problem ended up being.
Toji