64

I'm using XMLHttpRequest in JavaScript. However, it gives me an error, and I don't know what my problem is.
I have to parse an XML file and assign its contents to the webpage - here's my code:

<script = "text/javascript">

    window.onload = onPageLoad();
    var questionNum = 0;

    function onPageLoad(questionNum) {
        var xmlhttp = new XMLHttpRequest();
        xmlhttp.open("GET","quiz.xml");
        try {
            xmlhttp.send(null); // Here a xmlhttprequestexception number 101 is thrown 
        } catch(err) {
            document.getElementById("body").innerHTML += "\nXMLHttprequest error: " + err.description; // This prints "XMLHttprequest error: undefined" in the body.
        }
        xmlDoc = xmlhttp.responseXML;
        parser = new DOMParser(); // This code is untested as it does not run this far.
    }
</script>

My XML file is inside the same directory.

<question>
    <query>what is 2+2?</query>
    <option>4</option>
    <option>5</option>
    <option>3</option>
    <answer>4</answer>
</question>

Just for reference, I typically program in C# or Java, and I'm running my website on Google Chrome.

Davide Cannizzo
  • 2,826
  • 1
  • 29
  • 31
Muricula
  • 1,174
  • 3
  • 9
  • 16

3 Answers3

109

So there might be a few things wrong here.

First start by reading how to use XMLHttpRequest.open() because there's a third optional parameter for specifying whether to make an asynchronous request, defaulting to true. That means you're making an asynchronous request and need to specify a callback function before you do the send(). Here's an example from MDN:

var oXHR = new XMLHttpRequest();

oXHR.open("GET", "http://www.mozilla.org/", true);

oXHR.onreadystatechange = function (oEvent) {
    if (oXHR.readyState === 4) {
        if (oXHR.status === 200) {
          console.log(oXHR.responseText)
        } else {
           console.log("Error", oXHR.statusText);
        }
    }
};

oXHR.send(null);

Second, since you're getting a 101 error, you might use the wrong URL. So make sure that the URL you're making the request with is correct. Also, make sure that your server is capable of serving your quiz.xml file.

You'll probably have to debug by simplifying/narrowing down where the problem is. So I'd start by making an easy synchronous request so you don't have to worry about the callback function. So here's another example from MDN for making a synchronous request:

var request = new XMLHttpRequest();
request.open('GET', 'file:///home/user/file.json', false); 
request.send(null);

if (request.status == 0)
    console.log(request.responseText);

Also, if you're just starting out with Javascript, you could refer to MDN for Javascript API documentation/examples/tutorials.

kefir500
  • 4,184
  • 6
  • 42
  • 48
Nadir Muzaffar
  • 4,772
  • 2
  • 32
  • 48
  • I am still having this problem. When I try Nadir's second chunk of code I get the following error. I suspect this is my problem "XMLHttpRequest cannot load file:///Users/me/My%20Directory%20quiz/quiz.xml. Cross origin requests are only supported for HTTP." – Muricula Jan 15 '12 at 05:42
  • The url you enter should be the same as before... the url from the example is just an example url... – Nadir Muzaffar Jan 15 '12 at 07:18
  • 1
    what web server are you using?? – Nadir Muzaffar Jan 15 '12 at 07:19
  • The 'URL' I entered in my code was the path for the file on my machine, I just changed it for the post. I am not using a web server. I am wondering if this is the problem. I am just trying to retrieve the file from my drive. Do I need to download web server software? Or should I embed it within a Django or Rails server for testing? – Muricula Jan 15 '12 at 18:05
  • 1
    ya you'll need a web server, XMLHttpRequest is not very good with fetching local files...some browsers may allow it...anyways it seems like you're very knew to this so you should just start with setting upa basic website before you get into this stuff – Nadir Muzaffar Jan 15 '12 at 22:30
  • 1
    Why not try `if (oXHR.readyState === 4) { ` to change `if (oXHR.readyState == XMLHttpRequest.DONE) {` ... not just 4. – KingRider Jan 30 '17 at 16:42
  • works fine for me to call another serve on adonis backend – Betini O. Heleno Nov 16 '20 at 17:20
3

I see 2 possible problems:

Problem 1

  • the XMLHTTPRequest object has not finished loading the data at the time you are trying to use it

Solution: assign a callback function to the objects "onreadystatechange" -event and handle the data in that function

xmlhttp.onreadystatechange = callbackFunctionName;

Once the state has reached DONE (4), the response content is ready to be read.

Problem 2

  • the XMLHTTPRequest object does not exist in all browsers (by that name)

Solution: Either use a try-catch for creating the correct object for correct browser ( ActiveXObject in IE) or use a framework, for example jQuery ajax-method

Note: if you decide to use jQuery ajax-method, you assign the callback-function with jqXHR.done()

supertopi
  • 3,469
  • 26
  • 38
2

The problem is likely to lie with the line:

window.onload = onPageLoad();

By including the brackets you are saying onload should equal the return value of onPageLoad(). For example:

/*Example function*/
function onPageLoad()
{
    return "science";
}
/*Set on load*/
window.onload = onPageLoad()

If you print out the value of window.onload to the console it will be:

science

The solution is remove the brackets:

window.onload = onPageLoad;

So, you're using onPageLoad as a reference to the so-named function.

Finally, in order to get the response value you'll need a readystatechange listener for your XMLHttpRequest object, since it's asynchronous:

xmlDoc = xmlhttp.responseXML;
parser = new DOMParser(); // This code is untested as it doesn't run this far.

Here you add the listener:

xmlHttp.onreadystatechange = function() {
    if(this.readyState == 4) {
        // Do something
    }
}
Davide Cannizzo
  • 2,826
  • 1
  • 29
  • 31
CBusBus
  • 2,321
  • 1
  • 18
  • 26
  • Most of what you say is true, but to assign the return value of the function to `window.onload` means the function has to be executed, and should therefore work. Also note that it makes no difference where the function is declared, since function declarations in JavaScript are hoisted to the top of the scope in which they are declared. – James Allardice Jan 15 '12 at 01:19
  • I agree fully with your statement on declaration and have edited my answer; seemingly I was blinded by the erroneous brackets. – CBusBus Jan 15 '12 at 01:39