XmlHttpObject不会更改其readyState

时间:2009-09-10 14:04:42

标签: javascript ajax

我正在尝试使用JavaScript实现聊天客户端。使用以下构造函数构造客户端:

function ChatClient(endpointUrl) {
    this.xmlHttp = createXmlHttpRequest();  
    this.endpointUrl = endpointUrl;

    me = this;
    setInterval('me.receiveMessages()', FETCH_MESSAGES_INTERVAL);
}

function createXmlHttpRequest() {
    /* Create a new XMLHttpRequest object to talk to the Web server */
    var xmlHttp = false;
    /* @cc_on @ */
    /*
     * @if (@_jscript_version >= 5) try { xmlHttp = new
     * ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { xmlHttp = new
     * ActiveXObject("Microsoft.XMLHTTP"); } catch (e2) { xmlHttp = false; } }
     * @end @
     */

    if (!xmlHttp && typeof XMLHttpRequest != 'undefined') {
        xmlHttp = new XMLHttpRequest();
    }

    return xmlHttp;
}

聊天客户端应该能够在FETCH_MESSAGES_INTERVAL定义的时间间隔内从服务器请求消息。这是代码:

ChatClient.prototype.receiveMessages = function() {
    this.xmlHttp.open('GET', this.endpointUrl, true);
    this.xmlHttp.onreadystatechange = this.handleReceiveMessagesResponse();
    this.xmlHttp.send(null);
}

ChatClient.prototype.handleReceiveMessagesResponse = function() {
    console.log("readyState = " + this.xmlHttp.readyState);

    if (this.xmlHttp.readyState == 4) {
        var rawResponse = this.xmlHttp.responseText;
        document.getElementById('OutputArea').textContent = rawResponse;
    }
} 

问题是当调用handleReceiveMessagesReponse时,FireBug cosole显示this.xmlHttp.readyState始终为1(加载)。 FireBug还显示我的GET请求正在接收来自服务器的期望响应(状态200,字符串'Hello'作为正文)。有谁知道这段代码有什么问题?

2 个答案:

答案 0 :(得分:1)

调用handleReceiveMessagesResponse方法并将返回值(undefined)分配给onreadystatechange属性。我怀疑你并不打算这样做,事实上应该在该行的末尾留下()。但是,这仍然不起作用,因为this上下文不会像您期望的那样在被调用的函数中。

试试这个: -

ChatClient.prototype.receiveMessages = function() {
  var self = this;
  this.xmlHttp.open('GET', this.endpointUrl, true);
  this.xmlHttp.onreadystatechange = handleReceiveMessagesResponse;
  this.xmlHttp.send(null);


  function handleReceiveMessagesResponse() {
    console.log("readyState = " + self.xmlHttp.readyState);

    if (self.xmlHttp.readyState == 4) {
      var rawResponse = self.xmlHttp.responseText;
      document.getElementById('OutputArea').textContent = rawResponse;
    }
  }  
}

答案 1 :(得分:0)

这一行:

this.xmlHttp.onreadystatechange = this.handleReceiveMessagesResponse();

应该是:

this.xmlHttp.onreadystatechange = (function( fn ) {
  return function() {
    fn.handleReceiveMessagesResponse.apply( fn, arguments );
  };
})( this );

脱离我的头顶。这种疯狂背后的原因是:

  • onreadystatechange仅接受Function个值。调用该函数将返回其各自的返回值。
  • 因为你想保留对this的引用,我们必须通过将它分配给一个变量或者将它封装在一个闭包函数中来封装它,后者就是我所做的。
  • 然后,我们可以使用handleReceiveMessagesResponse / apply更改call方法的'this'变量的上下文。我也传递参数以防万一...