asp.net XMLHttpRequest 进度条以及lengthComputable always false的解决办法
一直用ajax好长时间了,对其原理也有一些了解,最近由于项目需要,使用ajax异步进度条的效果,就研究了一下,用原生的XMLHttpRequest实现进度条函数,XMLHttpRequest有以下函数可以使用,摘自(https://www.w3.org/TR/progress-events/)
type attribute value | Description | Times | When |
---|---|---|---|
loadstart |
Progress has begun. | Once. | First. |
progress |
In progress. | Zero or more. | After loadstart has been dispatched. |
error |
Progression failed. | Zero or once. | After the last progress has been dispatched, or after loadstart has been dispatched if progress has not been dispatched. |
abort |
Progression is terminated. | Zero or once. | |
load |
Progression is successful. | Zero or once. | |
loadend |
Progress has stopped. | Once. | After one of error , abort , or load has been dispatched. |
进度条函数主要使用progress事件。下面构造一个进度条实现的demo
1、构建页面代码
1 <div class="progress"> 2 <div id="pros" class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 0%;"> 3 </div> 4 </div> 5 <button id="trigger_ajax" type="button">请求数据</button> 6 <script type="text/javascript"> 7 var trigger = document.getElementById("trigger_ajax"); 8 trigger.onclick = function () { 9 var xhr = new XMLHttpRequest(); 10 xhr.onprogress = function (event) { 11 console.log(event.lengthComputable); 12 console.log(event.loaded); 13 if (event.lengthComputable) { 14 var loaded = parseInt(event.loaded / event.total * 100) + "%"; 15 $('#pros').width(loaded); 16 $('#pros').text(loaded); 17 } 18 } 19 xhr.open("post", "/Home/aaa", true); 20 xhr.send(null); 21 } 22 </script>
2、后台处理接口
1 [HttpPost] 2 public void aaa() 3 { 4 string result = string.Empty; 5 for (int i = 1; i <= 6000; i++) 6 { 7 result += i.ToString(); 8 int len = result.Length; 9 Response.Headers.Add("Content-Length", len.ToString()); 10 Response.Headers.Add("Content-Encoding", "UTF-8"); 11 Response.Write(result); 12 } 13 }
注意到
Response.Headers.Add("Content-Length", len.ToString());
Response.Headers.Add("Content-Encoding", "UTF-8");
,写出 http 头时候,附加 “Content-Length”和Content-Encoding,这样 JS 端的 progress 事件的 event.lengthComputable 值才会为 true
, event.total 才会在数据传输完毕之前取得值,否则 event.lengthComputable 值会返回 false
, event.total 在数据完成之前值都是0
。