XMLHttpRequest对象上缺少onreadystatechange()

时间:2013-04-05 13:44:02

标签: javascript ajax xmlhttprequest

(function (send) {

     XMLHttpRequest.prototype.send = function () {

         console.log(this.onreadystatechange); //null
         send.apply(this, arguments);
     };

})(XMLHttpRequest.prototype.send);

为什么this.onreadystatechange为空?根据{{​​3}},它应该存在并且属于function类型。

2 个答案:

答案 0 :(得分:9)

onreadystatechange 确实存在 ......这就是null的原因。如果它不存在,那将是undefined。这一切都取决于它是否已经设定。它显然已经是一个属性,因为它是null ...如果不是,它将是undefined ...或者至少"onreadystatechange" in this将是false

以下是一个例子:

var a = new XMLHttpRequest();
a.onreadystatechange = function () {
};
a.send();

您的控制台将记录function

如果你有:

var b = new XMLHttpRequest();
b.send();

您的控制台会记录null

以下是演示http://jsfiddle.net/3XKx7/

(我明确地留下了发送AJAX请求的其他步骤,这只是为了解释)

我并不是要暗示nullundefined之间存在关联 - 我只是说在创建新的XMLHttpRequest时,onreadystatechange将是在内部设置为null。是否将其设置为某个功能取决于您。

<强>更新

创建/发送XHR的正常方法是这个顺序:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {    // This and `open` could be flip-flopped
    // whatever
};
xhr.open("POST", url, true);
xhr.send("data=data");

我总是被告知/显示创建新的XMLHttpRequest,然后设置onreadystatechange并调用open的任何顺序,但只有在我们调用send之后才会这样做}。

所以,如果总是这样做,onreadystatechange(如果实际设置的话)不会是null而且会是function

由于您提到您使用的是jQuery,我决定尝试覆盖您想要的send方法,并进行jQuery $.ajax调用(不是手动发送XMLHttpRequest)。这是我的测试 - http://jsfiddle.net/3XKx7/1/

为什么onreadystatechangenull没有意义,因为jQuery 绑定到该事件,以便知道请求何时完成及其状态。所以我决定查看jQuery源代码。而我发现他们称之为命令的顺序是:

xhr.open()
xhr.send()
xhr.onreadystatechange = function () {

};

这意味着,当您覆盖send方法时,onreadystatechangenull,因为jQuery在调用{{1}之前未将其设置为 }。我不知道他们的理由......它可能是为了防止你正在做的事情...但我从来没有听说过或看到过这个惯例。

因此,您将其值设为send的原因是因为jQuery在调用null之后设置了onreadystatechange 。这意味着当您覆盖send并尝试访问send属性时,它尚未设置。

希望这是一个可以帮助您理解的示例:http://jsfiddle.net/dMP6q/16/

答案 1 :(得分:1)

你应该自己设置,当状态改变时会调用这个函数。它就像其他事件处理程序一样,如document.onloadyourelement.onclick等。

经典地你做

    var httpRequest = new XMLHttpRequest();
    httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState === 4) {
              if (httpRequest.status === 200) {
                  // use httpRequest.responseText
              }
        }
    };
    httpRequest.open('GET', url);
    httpRequest.send();