Search code examples
dompostxmlhttprequestasyncfileupload

XMLHttp request - wait for actual response and then add text to the page


Starting from the code provided by filedrag.js I've implemented an upload file async function.

The problem is that I can't retrieve the text once the call is done. Actually I'm sure the text is returned, since it shows up in firebug console once the POST request is done. The problem is that my code doesn't add it to the page.

Here's the code:

if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
    xmlhttp=new XMLHttpRequest();
} else {// code for IE6, IE5
    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}

function showHint(str,action,target,url) {
    xmlhttp.open("POST",url,true);
    xmlhttp.setRequestHeader("enctype","multipart/form-data");
    var fd = new FormData;
    fd.append('filexls', str);
    xmlhttp.send(fd);

   console.log(xmlhttp.status); 
      if (xmlhttp.readyState==4 && xmlhttp.status==200) {
            $('#successup').html(xmlhttp.responseText);
      }
}

I've done some testing and I think the problem is with the last part of the code. If I place the console.log(xmlhttp.status) before the if statement, it returns 0 (firebug at the end of the request returns 200), while if I place it inside the if nothing shows up in the console. So my best guess is that the problem is that the if statement runs before the actual request is done an so it returns false.


Solution

  • You need to assign an event listener to xmlhttp.onreadystatechange.

    Inside the listener, you can check the new readyState with xmlhttp.readyState. A readyState of 4 means completed. You can then access the following properties: xmlhttp.status, xmlhttp.responseText. You can also access headers either by using xmlhttp.getAllResponseHeaders() or by something like xmlhttp.getResponseHeader("Content-Type")

    If request status is falsy (check with if(!xmlhttp.status)) then the request failed. Otherwise the status is the HTTP status code of the response.

    You could do:

    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                    $('#successup').html(xmlhttp.responseText);
        }
    }
    

    Note: You can also use synchronous xmlhttprequests, but these block the entire UI before completing, so it's not that practical, unless when done inside a web worker. See documentation at MDN.

    Also, per http://blogs.msdn.com/b/xmlteam/archive/2006/10/23/using-the-right-version-of-msxml-in-internet-explorer.aspx , it's recommended to use new ActiveXObject("Msxml2.XMLHTTP") . The Microsoft.XMLHTTP identifier is deprecated. Note that this article is from 2006!

    The “Microsoft” namespace is actually older and is only implemented in MSXML3 for legacy support. It’s unfortunate we used the “better” name on the older version, but stick to the “msxml2” namespace when instantiating objects.