闻心阁

一蓑烟雨看苍生,半壶浊酒笑红尘

XMLHttpRequest中的进度事件响应及注意事项

2016-05-12 约 1 分钟读完 搬砖秘籍

在W3C的标准中制定了关于XMLHttpRequest 2级的相关规范,增加了许多极其有用的方法,如loadstart,loadend,progress等。最近写了一个应用需要监控上传信息,有一个细节很有意思,这里记录一下。

示例程序

Client

使用js发送post请求,代码如下:

<script type="text/javascript">
  var xhr, form; 

  xhr  = new XMLHttpRequest();
  form = new FormData();
  form.append("name", 'YQC');

  

  xhr.onload = function(e) {
    console.log( 'YOUR NAME IS ' + e.target.responseText );
  };
  
  xhr.upload.onloadstart = function(evt){
    console.log( 'loadstart事件触发.' );
  };
  
  xhr.upload.onloadend = function(evt){
    console.log( 'loadEnd事件触发.' );
  };
  
  xhr.upload.onprogress = function(evt){
    console.log( 'onprogress事件触发.' );
  };

  xhr.open("post", "http://localhost:3000/testSend", true);
  xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
  xhr.send("name=YQC");
</script>
Server

在nodejs中响应请求(使用express),简单代码如下:

router.post('/testSend', function(req, res, next) {
  console.log(req.body);
  res.send( req.body.name );
});

运行代码有如下输出:

可以发现看响应顺序是loadstart–> progress –> loadend

PS:在《JavaScript高级程序设计(第3版)》中P580页中,作者介绍loadend并没有被实现,现成在本人的机器(chrome版本 50.0.2661.94 m)已经支持此事件了。

一个前提

但是所以这些都要一个前提:请求异步,如果改成同步的呢?

xhr.open("post", "http://localhost:3000/testSend", false);

效果如下:

看,在同步请求的情况下,所有的进度事件都是空谈。所以如果要使用XMLHttpRequest 2级的进度事件,这里要将请求设置为异步。