6

W3C 规范建议以下实现:一些简单的代码来处理通过网络获取的 XML 文档中的数据:

function processData(data) {
  // taking care of data
}

function handler() {
  if(this.readyState == this.DONE) {
    if(this.status == 200 &&
       this.responseXML != null &&
       this.responseXML.getElementById('test').textContent) {
      // success!
      processData(this.responseXML.getElementById('test').textContent);
      return;
    }
    // something went wrong
    processData(null);
  }
}

var client = new XMLHttpRequest();
client.onreadystatechange = handler;
client.open("GET", "unicorn.xml");
client.send();

这个实现真的正确吗?

在调试期间,我发现readystatechanged事件处理程序在同一行中被多次调用,且readyState == 4的值相同。我猜这种行为是正确的,因为规范说每次状态更改都必须触发事件,并且readyState 必须始终等于当前状态,所以如果多个事件堆积在事件队列中,很明显,一个会收到多次调用 readyState == 4。

http://jsfiddle.net/44b3P/ - 这是上面的示例,在发送请求后添加了调试器调用以暂停执行,并在 processData 中使用 alert()。取消暂停执行后,您将收到 3 个警报。

这个来自 w3c 的示例似乎被复制并粘贴到网络中的多个位置——特别是 OpenSocial 似乎以这种方式处理 xhr 事件。这是正确的吗?

4

2 回答 2

15

在 Chrome 开发人员工具中进行调试时,我也看到了相同的行为(DONE 200 被多次点击,即 2...n 次)。

为了让它始终在调试模式下工作,我找到了两个选项:

  1. 用于onload验证 XMLHTMLRequest W3C 规范是否成功

    client.onload = 处理程序;

    此版本不适用于 IE8。必须是实现了XMLHttpRequestEventTarget接口的浏览器

  2. onreadystatechange一有状态就删除处理程序DONE 200

    client.onreadystatechange = function() {
        // check if request is complete
        if (this.readyState == this.DONE) {
            if (this.onreadystatechange) {
                client.onreadystatechange = null;
                handler();
            }
        }
    };
    

我还为这个问题在Chromium中打开了一个问题,提供你的小提琴(谢谢!)

于 2012-11-27T13:19:24.243 回答
0

我从来没有让我的onreadystatechange处理程序以 4 执行多次readyState

我认为假设在 DONE 上执行一次是正确的。

于 2012-10-06T16:54:46.790 回答