一般地,使用readystatechange事件探测HTTP请求的完成。XHR2规范草案定义了进度事件Progress Events规范,XMLHttpRequest对象在请求的不同阶段触发不同类型的事件,所以它不再需要检査readyState属性。这个草案定义了与客户端服务器通信有关的事件。这些事件最早其实只针对XHR操作,但目前也被其他API(如File API)借鉴。本文将详细介绍进度事件

基础

  有以下6个进度事件

  loadstart: 在接收到响应数据的第一个字节时触发

  progress: 在接收响应期间持续不断地触

  error: 在请求发生错误时触发

  abort: 在因为调用abort()方法而终止连接时触发

  load: 在接收到完整的响应数据时触发

  loadend: 在通信完成或者触发error、abort或load事件后触发

  timeout: 超时发生时触发

  [注意]IE9-浏览器不支持以上事件(IE9浏览器仅支持load事件)

  每个请求都从触发loadstart事件开始,接下来,通常每隔50毫秒左右触发一次progress事件,然后触发 loaderrorabort 或 timeout 事件中的一个,最后以触发loadend事件结束

  对于任何具体请求,浏览器将只会触发load、abort、timeout和error事件中的一个。XHR2规范草案指出一旦这些事件中的一个发生后,浏览器应该触发loadend事件

load

  响应接收完毕后将触发load事件,因此也就没有必要去检查readyState属性了。但一个完成的请求不一定是成功的请求,例如,load事件的处理程序应该检查XMLHttpRequest对象的status状态码来确定收到的是“200 OK”而不是“404 Not Found”的HTTP响应

<button id="btn">获取信息</button>
<div id="result"></div>
<script>
btn.onclick = function(){
//创建xhr对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//进度事件
xhr.onload = function(){
if(xhr.status == 200){
result.innerHTML += xhr.responseText;
}
}
//发送请求
xhr.open('get','message.xml',true);
xhr.send();
}
</script>

progress

  progress事件会在浏览器接收新数据期间周期性地触发。而onprogress事件处理程序会接收到一个event对象,其target属性是XHR对象,但包含着三个额外的属性lengthComputableloadedtotal。其中,lengthComputable是一个表示进度信息是否可用的布尔值loaded表示已经接收的字节数total表示根据Content-Length响应头部确定的预期字节数。有了这些信息,就可以为用户创建一个进度指示器了

<button id="btn">获取信息</button>
<div id="result"></div>
<div id="music"></div>
<script>
btn.onclick = function(){
//创建xhr对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
//进度事件
xhr.onprogress = function(e){
e = e || event;
if (e.lengthComputable){
result.innerHTML = "Received " + e.loaded + " of " + e.total + " bytes";
}
};
xhr.onload = function(e){
var data = xhr.response;
e = e || event;
if(xhr.status == 200){
var audio = document.createElement('audio');
audio.onload = function(){
URL.revokeObjectURL(audio.src);
}
audio.src = URL.createObjectURL(data);
console.log(audio);
audio.setAttribute('controls','');
if(!music.innerHTML){
music.appendChild(audio);
}
}
};
//发送请求
xhr.open('get','myocean.mp3',true);
xhr.responseType = 'blob';
xhr.send();
}
</script>

上传进度

  除了为监控HTTP响应的加载定义的这些有用的事件外,XHR2也给出了用于监控HTTP请求上传的事件。在实现这些特性的浏览器中,XMLHttpRequest对象将有upload属性。upload属性值是一个对象,它定义了addEventListener()方法和整个progress事件集合,比如onprogress和onload(但upload对象没有定义onreadystatechange属性,upload仅能触发新的事件类型)

  能仅仅像使用常见的progress事件处理程序一样使用upload事件处理程序。对于XMLHttpRequest对象,设置XHR.onprogress监控响应的下载进度,并且设置XHR.upload.onprogress以监控请求上传进度

<input type="file" name="file1" id="file1" style="display:none">
<button id="btn">上传文件</button>
<div id="pro"></div>
<div id="result"></div>
<script>
btn.onclick = function(){
file1.click();
pro.innerHTML = result.innerHTML = '';
}
file1.onchange = function(){
//创建xhr对象
var xhr;
if(window.XMLHttpRequest){
xhr = new XMLHttpRequest();
}else{
xhr = new ActiveXObject('Microsoft.XMLHTTP');
}
var data = file1.files[0];
//上传事件
xhr.upload.onprogress = function(e){
e = e || event;
if (e.lengthComputable){
pro.innerHTML = "上传进度为:" + e.loaded + " of " + e.total + " bytes" + ';百分比为:' + e.loaded/e.total;
}
}
xhr.onload = function(e){
var data = xhr.responseText;
e = e || event;
if(xhr.status == 200){
result.innerHTML = data;
}
};
//发送请求
xhr.open('post','pp.php',true);
xhr.setRequestHeader("content-type",data.type);
xhr.send(data);
}
</script>
<?php
error_reporting(E_ALL & ~E_NOTICE);
touch($file);
if(preg_match('/image/',apache_request_headers()['content-type'])){
$file = 'photo/test.jpg';
binary_to_file($file);
echo '文件上传成功!';
}else{
echo '文件格式不正确,请选择图片文件';
}
function binary_to_file($file){
$content = $GLOBALS['HTTP_RAW_POST_DATA']; // 需要php.ini设置
if(empty($content)){
$content = file_get_contents('php://input'); //不需要php.ini设置,内存压力小
}
$ret = file_put_contents($file, $content, true);
return $ret;
};
?>

其他事件

  HTTP请求无法完成有3种情况,对应3种事件。如果请求超时,会触发timeout事件。如果请求中止,会触发abort事件。最后,像太多重定向这样的网络错误会阻止请求完成,但这些情况发生时会触发error事件

  可以通过调用XMLHttpRequest对象abort()方法取消正在进行HTTP请求。调用abort()方法在这个对象上触发abort事件

  调用abort()的主要原因是完成取消或超时请求消耗的时间太长或当响应变得无关时。假如使用XMLHttpRequest为文本输入域请求自动完成推荐。如果用户在服务器的建议达到之前输入了新字符,这时等待请求不再有用,应该中止

  XHR对象的timeout属性等于一个整数,表示多少毫秒后,如果请求仍然没有得到结果,就会自动终止。该属性默认等于0,表示没有时间限制

  如果请求超时,将触发ontimeout事件

var xhr = new XMLHttpRequest();
btn.onclick = function(){
xhr.abort();
};
xhr.ontimeout = function(){
console.log('The request timed out.');
}
xhr.timeout = 100;
xhr.onabort = function(){
console.log("The transfer has been canceled by the user.");
}
xhr.onerror = function(){
console.log("An error occurred while transferring the file.");
}
xhr.onloadend = function(){
console.log("请求结束");
}
 

[转]深入理解ajax系列——进度事件的更多相关文章

  1. 深入理解ajax系列第五篇——进度事件

    前面的话 一般地,使用readystatechange事件探测HTTP请求的完成.XHR2规范草案定义了进度事件Progress Events规范,XMLHttpRequest对象在请求的不同阶段触发 ...

  2. 深入理解ajax系列第一篇——XHR对象

    × 目录 [1]创建对象 [2]发送请求 [3]接收响应[4]异步处理[5]实例演示 前面的话 ajax是asynchronous javascript and XML的简写,中文翻译是异步的java ...

  3. 深入理解ajax系列第九篇——jQuery中的ajax

    前面的话 jQuery提供了一些日常开发中需要的快捷操作,例如load.ajax.get和post等,使用jQuery开发ajax将变得极其简单.这样开发人员就可以将程序开发集中在业务和用户体验上,而 ...

  4. 深入理解ajax系列第八篇——表单提交

    前面的话 在以前,网站的用户与后端交互的主要方式是通过HTML表单的使用.表单的引入在1993年,由于其简单性和易用性,直到电子商务出现之前一直保持着重要位置.理解表单提交,对于更深入地理解ajax是 ...

  5. 深入理解ajax系列第八篇

    前面的话 在以前,网站的用户与后端交互的主要方式是通过HTML表单的使用.表单的引入在1993年,由于其简单性和易用性,直到电子商务出现之前一直保持着重要位置.理解表单提交,对于更深入地理解ajax是 ...

  6. 深入理解ajax系列第九篇

    前面的话 jQuery提供了一些日常开发中需要的快捷操作,例如load.ajax.get和post等,使用jQuery开发ajax将变得极其简单.这样开发人员就可以将程序开发集中在业务和用户体验上,而 ...

  7. 深入理解ajax系列第五篇

    前面的话 一般地,使用readystatechange事件探测HTTP请求的完成.XHR2规范草案定义了进度事件Progress Events规范,XMLHttpRequest对象在请求的不同阶段触发 ...

  8. [AJAX系列]onreadystatechange事件

    onreadystatechange事件: 当请求被发送到服务器时,我们需要执行一些基于响应的任务 每当readyState改变时,就会触发onreadystatechange事件 readyStat ...

  9. 深入理解 ajax系列第一篇(XHR 对象)

    1999年,微软公司发布了IE5, 第一次引入新功能:允许javascript 脚本向服务器发起 hffp 请求.这个功能方式并没有被引起注意,知道2004年 Gmail 发布和 Google Map ...

随机推荐

  1. postgresql数据库安装后的pgadmin4切换中文

    如图所示

  2. 第十二章 Odoo 12开发之报表和服务端 QWeb

    报表是业务应用非常有价值的功能,内置的 QWeb 引擎是报表的默认引擎.使用 QWeb 模板设计的报表可生成 HTML 文件并被转化成 PDF.也就是说我们可以很便捷地利用已学习的 QWeb 知识,应 ...

  3. lumen框架使用Elasticsearch详解

    该博文是集合几个博客踩坑得来的,百度热搜前几篇都是缺胳膊少腿的,所以结合几篇博客实现了一遍. 一.lumen使用Elasticsearch 首先需要搭建好的elasticsearch环境: http: ...

  4. 19-10-26-Night-D

    压表的技巧. ZJ一下: T1,考试不会哈夫曼树只压到$1MB$最后截掉了一部分. T2,直接暴力丢上去.$\Theta(N+\sqrt{N}\log N)$ T3,现场码出左右旋然后就不会了$QAQ ...

  5. 洛谷P1291 [SHOI2002]百事世界杯之旅

    题目链接: kma 题目分析: 收集邮票的弱弱弱弱化版,因为是期望,考虑倒推 设\(f[i]\)表示现在已经买齐了\(i\)种,距离买完它的剩余期望次数 那么下一次抽有\(\frac{i}{n}\)的 ...

  6. Cesium官方教程9--粒子系统

    原文地址:https://cesiumjs.org/tutorials/Particle-Systems-Tutorial/ 粒子系统介绍 这篇教程带你学习Cesium的粒子相关API,比如如何在你的 ...

  7. Linux 启动、关闭、重启服务的两种方式

    1.一种是可以使用service脚本来调度,如: service 服务名 startservice 服务名 stopservice 服务名 restart 2.第二种可以直接进入/etc/init.d ...

  8. 轻量级IoC框架Ninject.NET搭建

    说在之前的话 IOC的概念相信大家比较熟悉了,习惯性称之为依赖注入或控制反转,园子里对基于MVC平台IOC设计模式已经相当多了,但大家都只知道应该怎么应用一个IOC模式,比如Ninject, Unit ...

  9. .net core 使用swagger生成API文档

    [1]安装Swashbuckle.AspNetCore包 [2]在Startup.cs中注册swagger //注册Swagger生成器,定义一个和多个Swagger 文档 services.AddS ...

  10. wpf中在style的template寻找ControlTemplate和DataTemplate的控件

    一.WPF中的两棵树 WPF中每个控件的Template都是由ControlTemplate构成,ControlTemplate包含了构成该控件的各种子控件,这些子控件就构成了VisualTree:而 ...