XMLHttpRequest 1.0 只是把已有的 XMLHttpRequest 对象的实现细节描述出来,而 XMLHttpRequest 2.0 则进一步发展了 XMLHttpRequest;并非所有浏览器都完整实现了 XMLHttpRequest 2.0 规范,但是所有浏览器都实现了 XMLHttpRequest 2.0 规定的部分内容。
XMLHttpRequest 1.0 API 存在以下缺陷。
2014 年 11 月 W3C 正式发布 XMLHttpRequest Level 2(http://www.w3.org/TR/XMLHttpRequest2/)标准规范,新增了很多实用功能,推动异步交互在 JavaScript 中的应用。说明如下:
XMLHttpRequest 2.0 为 XMLHttpRequest 对象新增 timeout 属性,使用该属性可以设置 HTTP 请求时限。
xhr.timeout = 3000;
上面语句将异步请求的最长等待时间设为 3000 毫秒。超过时限,就自动停止 HTTP 请求。
与之配套的还有一个 timeout 事件,用来指定回调函数。
xhr.ontimeout = function (event) {
console.log('请求超时!');
}
在 JavaScript 中,XMLHttpRequest 2.0 新增 FormData 对象,使用它可以处理表单数据。
1) 新建 FormData 对象。
var formData = new FormData();
2) 为 FormData 对象添加表单项。
form.append('user', '张三');
form.append('pass', '123456');
3) 直接传送 FormData 对象。
xhr.send(formData);
4) FormData 对象也可以直接获取网页表单的值。
var form = document.getElementById('myform');
var formData = new FormData(form);
formData.append('grade', '2'); //添加一个表单项
xhr.open('POST', 'form.action');
xhr.send(formData);
新版 XMLHttpRequest 对象不仅可以发送文本信息,还可以上传文件。使用 send() 方法可以发送字符串、Document 对象、表单数据、Blob 对象、文件和 ArrayBuffer 对象。
设计一个“选择文件”的表单元素(input[type="file"]),并将它装入 FormData 对象。
var formData = new FormData();
for (var i = 0; i < files.length; i ++){
formData.append('files[]', files[i]);
}
然后,发送 FormData 对象给服务器。
xhr.send(formData);
XMLHttpRequest 2.0 版本允许向不同域名的服务器发出 HTTP 请求。使用跨域资源共享的前提是:浏览器必须支持这个功能,且服务器端必须同意这种跨域。如果能同时满足上面两个条件,则代码的写法与不跨域的请求完全一样。例如:
var xhr = createXHR();
var url = 'http://other.server/and/path/to/script'; //请求的跨域文件
xhr.open('GET', url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
}
xhr.send();
新版本的 XMLHttpRequest 对象新增 responseType 和 response 属性。
XMLHttpRequest 1.0 版本只能从服务器接收文本数据,而 XMLHttpRequest 2.0版本则可以接收二进制数据。使用新增的 responseType 属性,可以从服务器接收二进制数据。
可以把 responseType 设为 blob,表示服务器传回的是二进制对象。
var xhr = new XMLHttpRequest ();
xhr.open('GET', '/path/to/image.png');
xhr.responseType = 'blob';
接收数据的时候,用浏览器自带的 Blob 对象即可。
var blob = new Blob ([xhr.response], {type : 'image/png'});
是读取 xhr.response,而不是 xhr.responseText。
可以将 responseType 设为 arraybuffer,把二进制数据装在一个数组里。
var xhr = new XMLHttpRequest ();
xhr.open('GET', '/path/to/image.png');
xhr.responseType = 'arraybuffer';
接收数据的时候,需要遍历这个数组。
var arrayBuffer = xhr.response;
if (arrayBuffer) {
var byteArray = new Unit8Array (arrayBuffer);
for (var i = 0; i < byteArray.byteLength; i ++ ) {
//执行代码
}
}
新版本的 XMLHttpRequest 对象新增了一个 progress 事件,用来返回进度信息。它分成上传和下载两种情况。下载的 progress 事件属于 XMLHttpRequest 对象,上传的 progress 事件属于 XMLHttpRequest.upload 对象。
1) 先定义 progress 事件的回调函数。
xhr.onprogress = updateProgress;
xhr.upload.onprogress = updateProgress;
2) 在回调函数里面,使用这个事件的一些属性。
function updateProgress (event) {
if (event.lengthComputable) {
var percentComplete = event.loaded / event.total;
}
}
上面代码中,event.total 是需要传输的总字节,event.loaded 是已经传输的字节。如果 event.lengthComputable 不为真,则 event.total 等于 0。
与 progress 事件相关的,还有其他 5 个事件,可以分别指定回调函数。