【问题标题】:XMLHttpreques onprogress event not called未调用 XMLHttprequest onprogress 事件
【发布时间】:2013-11-27 13:14:47
【问题描述】:

不要将XMLHttprequest.onprogressXMLHttprequest.upload.onprogress 混淆。

我使用这个XMLHttprequest.onprogress 事件在长轮询请求结束之前处理服务器输入。在服务器上,脚本可能如下所示:

while(condition && timeout condition) {
    if(data available) {
        echo $data;
        flush();
    }
}

javascript onprogress 事件如下所示:

  function onprogressCallback() {     
    //Start at the current position in the input, anything before has already been sent to onData()
    var seektmp = seeker;

    //Loop through the input and seek delimiters
    while(seektmp<_this.http.responseText.length&&!forcedDisconnect) {
      if(_this.http.responseText[seektmp]==_this.delimiter) {
        //If a delimiter has been found, send the fragment before to onData
        var data = _this.http.responseText.substr(seeker,seektmp-seeker); 
        //Only call on nonempty data, empty data are used to keep onprogress event running
        if(data!="")
          _this.onData(data);
        //Skip the original seeker to the end of data that has been read (+1 for delimiter)

        //console.log("DATA!: '",_this.http.responseText.substr(seeker,seektmp-seeker),"'");
        seeker=seektmp+1;   //todo: +delimiter size, instead of just 1
      }      
      //iterate 1 character, until the end of data 
      seektmp++;
    }  
  }

上述代码中的_this 指的是来自包含此函数的命名空间的此引用。 _this.http 是我用于长轮询的 http 请求。

我将这个分配给 httpreques 对象:

this.http.onprogress = onprogressCallback;

现在的问题:

当我输出少量数据时,onprogress entent 被调用。数据保存在某种缓冲区中,无法访问它们,但是,我可以在 firebug 中看到它们。

但是,如果我继续向浏览器发送无用数据的垃圾邮件,例如 \n 的负载,它会按预期工作:

while(condition && timeout condition) {
    if(data available) {
        echo $data."\n";
        flush();
    }
    else {
        echo "\n";  //Endless stream of \n keeps browser calling the onprogress event
        flush();
    }
}

但这真的很糟糕。这样的输出很难调试并且占用大量内存。

【问题讨论】:

    标签: javascript xmlhttprequest long-polling


    【解决方案1】:

    我遇到了和你一样的问题。

    我可以看到,浏览器不会触发 onprogress 事件,除非他们收到了最少量的数据。我不确定所有浏览器的这个值是多少。但就我而言,我添加了空格,因此第一条消息的最小大小为 2048 个字符。

    我正在使用像下面这样简单的东西(PHP)

    if (strlen($data) < 2048) {
        $data = str_pad($data, 2048 - strlen($data));
    }
    

    请注意,您的网络服务器可能会去除额外的空白,因此如果您没有在浏览器中看到额外的空白,请确保它没有这样做。

    【讨论】:

      猜你喜欢
      • 2019-06-20
      • 2011-07-26
      • 2017-09-06
      • 2015-03-02
      • 2014-12-11
      • 2021-08-14
      • 2023-03-17
      • 1970-01-01
      • 2012-11-05
      相关资源
      最近更新 更多