微软最早以ActiveX对象的形式在IE5中引入了XMLHttpRequest对象,经Google发扬光大之后,目前所有的浏览器都已经支持XMLHttpRequest了,目前W3C正在制定XMLHttpRequest Level 2标准草案,相对于原来的XMLHttpRequest,新标准的XMLHttpRequest有了很大的改进,提供了很多新的功能。
本文就新旧XMLHttpRequest对象进行一个简单的比较,并介绍新标准的XMLHttpRequest对象的改进之处。
原来的XMLHttpRequest对象的缺点:
1.只支持文本数据的传递,不支持二进制数据。
2.传递数据的时候,没有progress事件,不能实时显示传递的进度信息。
3.受同源策略的限制,不能发送跨域的请求。
新标准的XMLHttpRequest的改进:
1.可以传递二进制数据。
2.在服务器端设置了CORS允许跨域请求的时候,可以获取跨域的数据。
3.可以使用原生的FormData对象来管理要发送的表单数据。
4.提供了progress事件,可以提供进度信息。在下载和上传的时候,都有progress事件,下载的时候,progress事件由XMLHttpRequest本身触发,上传的时候,由XMLHttpRequest.upload对象触发,可以通过addEventListener来添加事件处理方法。
利用新标准的XMLHttpRequest对象,我们可以非常方便的实现文件AJAX上传功能。
HTML:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>使用XMLHttpRequest上传文件</title>
<style type="text/css">
.container {
width: 500px;
margin: 0 auto;
}
.progress-bar {
border: 1px solid #000;
}
.progress {
width: 0;
background: #DEDEDE;
height: 20px;
}
</style>
</head>
<body>
<div class="container">
<p>
选择文件:
<input type="file" id="ipt-file"/>
<button type="button" id="btn-upload">上传</button>
</p>
<div class="progress-bar">
<div class="progress" id="progress"></div>
</div>
<p id="info"></p>
</div>
<script src="./js/upload.js"></script>
</body>
</html>
JavaScript:
upload.js的具体代码如下:
var button = document.querySelector("#btn-upload"),
input = document.querySelector("#ipt-file"),
progress = document.querySelector("#progress"),
info = document.querySelector("#info");
var upload = function() {
if (input.files.length === 0) {
console.log("未选择文件");
return;
}
var formData = new FormData();
formData.append("file", input.files[0]);
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
console.log(xhr.responseText);
info.innerHTML = xhr.responseText;
}
};
xhr.upload.addEventListener("progress", function(event) {
if(event.lengthComputable){
progress.style.width = Math.ceil(event.loaded * 100 / event.total) + "%";
}
}, false);
xhr.open("POST", "./upload");
xhr.send(formData);
};
button.addEventListener("click", upload, false);