title: INVALID_STATE_ERR: DOM Exception 11
body: <p>I'm developing a simple auxiliary class to send requests using XmlHttpRequest (code below). But I cant make it work. At google chrome, for example, I get the error <code>INVALID_STATE_ERR: DOM Exception 11</code> and at the other browsers I get a status == 0.</p>
  
  <pre><code>//@method XRequest: Object constructor. As this implements a singleton, the object can't be created calling the constructor, GetInstance should be called instead
  function XRequest() {
      this.XHR = XRequest.CreateXHR();
  }
  XRequest.instance = null;
  
  //@method static GetInstance: Creates a singleton object of type XRequest. Should be called whenever an object of that type is required.
  //@return: an instance of a XRequest object
  XRequest.GetInstance = function() {
      if(XRequest.instance == null) {
          XRequest.instance = new XRequest();
      }
      return XRequest.instance;
  }
  
  //@method static CreateXHR: Implments a basic factory method for creating a XMLHttpRequest object
  //@return: XMLHttp object or null
  XRequest.CreateXHR = function() {
      var xhr = null;
      var factory = [
          function() { return new XMLHttpRequest(); },
          function() { return new ActiveXObject("Msxml2.XMLHTTP"); },
          function() { return new ActiveXObject("Microsoft.XMLHTTP"); }
      ];
  
      for(var i = 0; i &lt; factory.length; ++i) {
          var f = factory[i];
          xhr = f();
          if(xhr) return xhr;
      }
      return null;
  }
  
  XRequest.prototype.SetRequestHeader = function(name, value) {
      if(this.XHR) {
          this.XHR.setRequestHeader(name, value);
      }
  }
  
  XRequest.prototype.SendRequest = function(args) {
      var async = true;
      var type = "";
      var url = "";
      var username = "";
      var password = "";
      var body = null;
      var success = null; 
      var failure = null;
  
      for(e in args) {
          switch(e) {
              case "async":
                  async = args[e];
                  break;
              case "type":
                  type = args[e];
                  break;
              case "success":
                  success = args[e];
                  break;
              case "failure":
                  failure = args[e];
                  break;
              case "url":
                  url = args[e];
                  break;
              case "username":
                  username = args[e];
                  break;
              case "password":
                  password = args[e];
                  break;
              case "body":
                  body = args[e];
              break;
              case "setHeader":
                  var h = args[e].split(":");
                  if(h.length == 2) {
                      this.SetRequestHeader(h[0], h[1]);
                  }
                  break;
          }
      }
  
      var that = this;
      this.XHR.onreadystatechange = function() {
          alert("readyState == " + that.XHR.readyState + "  status == " + that.XHR.status);
          if(that.XHR.readyState == 4) {
              if(that.XHR.status == 200 || that.XHR.status == 0) {
                  if(success) success(that.XHR);
              } else {
                  if(failure) failure();
              }
          }
      };
      this.XHR.open(type, url, async, username, password);
      this.XHR.send(body);
  }
  </code></pre>
  
  <p><strong>Example of usage:</strong></p>
  
  <pre><code>&lt;script language="javascript"&gt;
      function onLoad() {
          var x = XRequest.GetInstance();
          x.SendRequest({type:"GET",
              setHeader:"Accept:text/html, image/png, image/*, */*",
              url: "http://your_server.com/getData?param1=test",
              success:onSuccess, failure:onFail
          });
      }
  
      function onSuccess(obj) {
          alert("OK");                
      }
  
      function onFail() {
          alert("Not at this time!");
      }
  &lt;/script&gt;
  </code></pre>