通常地,使用readystatechange事件探测HTTP请求的完成。XHR2规范草案定义了进度事件Progress Events规范,XMLHttpRequest对象在请求的不一样阶段触发不一样类型的事件,因此它再也不须要检査readyState属性。这个草案定义了与客户端服务器通讯有关的事件。这些事件最先其实只针对XHR操做,但目前也被其余API(如File API)借鉴。本文将详细介绍进度事件php
基础
有如下6个进度事件apache
loadstart:在接收到响应数据的第一个字节时触发浏览器
progress:在接收响应期间持续不断地触服务器
error:在请求发生错误时触发网络
abort:在由于调用abort()方法而终止链接时触发app
load:在接收到完整的响应数据时触发post
loadend:在通讯完成或者触发error、abort或load事件后触发code
timeout:超时发生时触发xml
[注意]IE9-浏览器不支持以上事件(IE9浏览器仅支持load事件)对象
每一个请求都从触发loadstart事件开始,接下来,一般每隔50毫秒左右触发一次progress事件,而后触发load、error、abort或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对象,但包含着三个额外的属性:lengthComputable、loaded和total。其中,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("请求结束");
}