(转)Ajax_XMLHttpRequest Level 2
2012-09-12 16:42
225 查看
XMLHttpRequest 是一个浏览器接口,使得 Javascript 可以进行 HTTP (S) 通信。
最早,微软在 IE 5 引进了这个接口。因为它太有用,其他浏览器也模仿部署了,ajax 操作因此得以诞生。
但是,这个接口一直没有标准化,每家浏览器的实现或多或少有点不同。HTML 5 的概念形成后,W3C 开始考虑标准化这个接口。2008年 2 月,就提出了 XMLHttpRequest Level 2 草案。
这个 XMLHttpRequest 的新版本,提出了很多有用的新功能,将大大推动互联网革新。本文就对这个新版本进行详细介绍。
一、老版本的 XMLHttpRequest 对象
在介绍新版本之前,我们先回顾一下老版本的用法。
首先,新建一个 XMLHttpRequest 的实例。
然后,向远程主机发出一个 HTTP 请求。
接着,就等待远程主机做出回应。这时需要监控 XMLHttpRequest 对象的状态变化,指定回调函数。
上面的代码包含了老版本 XMLHttpRequest 对象的主要属性:
* xhr.readyState:XMLHttpRequest 对象的状态,等于 4 表示数据已经接收完毕。
* xhr.status:服务器返回的状态码,等于 200 表示一切正常。
* xhr.responseText:服务器返回的文本数据
* xhr.responseXML:服务器返回的 XML 格式的数据
* xhr.statusText:服务器返回的状态文本。
二、老版本的缺点
老版本的 XMLHttpRequest 对象有以下几个缺点:
* 只支持文本数据的传送,无法用来读取和上传二进制文件。
* 传送和接收数据时,没有进度信息,只能提示有没有完成。
* 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据。
三、新版本的功能
新版本的 XMLHttpRequest 对象,针对老版本的缺点,做出了大幅改进。
* 可以设置 HTTP 请求的时限。
* 可以使用 FormData 对象管理表单数据。
* 可以上传文件。
* 可以请求不同域名下的数据(跨域请求)。
* 可以获取服务器端的二进制数据。
* 可以获得数据传输的进度信息。
下面,我就一一介绍这些新功能。
四、HTTP 请求的时限
有时,ajax 操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。
新版本的 XMLHttpRequest 对象,增加了 timeout 属性,可以设置 HTTP 请求的时限。
上面的语句,将最长等待时间设为 3000 毫秒。过了这个时限,就自动停止 HTTP 请求。与之配套的还有一个 timeout 事件,用来指定回调函数。
目前,Opera、Firefox 和 IE 10 支持该属性,IE 8 和 IE 9 的这个属性属于 XDomainRequest 对象,而 Chrome 和 Safari 还不支持。
五、FormData 对象
ajax 操作往往用来传递表单数据。为了方便表单处理,HTML 5 新增了一个 FormData 对象,可以模拟表单。
首先,新建一个 FormData 对象。
然后,为它添加表单项。
最后,直接传送这个 FormData 对象。这与提交网页表单的效果,完全一样。
FormData 对象也可以用来获取网页表单的值。
六、上传文件
新版 XMLHttpRequest 对象,不仅可以发送文本信息,还可以上传文件。
假定 files 是一个"选择文件"的表单元素(input[type="file"]),我们将它装入 FormData 对象。
然后,发送这个 FormData 对象。
七、跨域资源共享(CORS)
新版本的 XMLHttpRequest 对象,可以向不同域名的服务器发出 HTTP 请求。这叫做"跨域资源共享"(Cross-origin resource sharing,简称 CORS)。
使用"跨域资源共享"的前提,是浏览器必须支持这个功能,而且服务器端必须同意这种"跨域"。如果能够满足上面的条件,则代码的写法与不跨域的请求完全一样。
目前,除了 IE 8 和 IE 9,主流浏览器都支持 CORS,IE 10 也将支持这个功能。服务器端的设置,请参考《Server-Side Access Control》。
八、接收二进制数据(方法A:改写 MIMEType)
老版本的 XMLHttpRequest 对象,只能从服务器取回文本数据(否则它的名字就不用 XML 起首了),新版则可以取回二进制数据。
这里又分成两种做法。较老的做法是改写数据的 MIMEType,将服务器返回的二进制数据伪装成文本数据,并且告诉浏览器这是用户自定义的字符集。
然后,用 responseText 属性接收服务器返回的二进制数据。
由于这时,浏览器把它当做文本数据,所以还必须再一个个字节地还原成二进制数据。
最后一行的位运算"c & 0xff",表示在每个字符的两个字节之中,只保留后一个字节,将前一个字节扔掉。原因是浏览器解读字符的时候,会把字符自动解读成 Unicode 的 0xF700-0xF7ff 区段。
八、接收二进制数据(方法B:responseType 属性)
从服务器取回二进制数据,较新的方法是使用新增的 responseType 属性。如果服务器返回文本数据,这个属性的值是"TEXT",这是默认值。较新的浏览器还支持其他值,也就是说,可以接收其他格式的数据。
你可以把 responseType 设为 blob,表示服务器传回的是二进制对象。
接收数据的时候,用浏览器自带的 Blob 对象即可。
注意,是读取 xhr.response,而不是 xhr.responseText。
你还可以将 responseType 设为 arraybuffer,把二进制数据装在一个数组里。
接收数据的时候,需要遍历这个数组。
更详细的讨论,请看 Sending and Receiving Binary Data。
九、进度信息
新版本的 XMLHttpRequest 对象,传送数据的时候,有一个 progress 事件,用来返回进度信息。
它分成上传和下载两种情况。下载的 progress 事件属于 XMLHttpRequest 对象,上传的 progress 事件属于 XMLHttpRequest.upload 对象。
我们先定义 progress 事件的回调函数。
然后,在回调函数里面,使用这个事件的一些属性。
上面的代码中,event.total 是需要传输的总字节,event.loaded 是已经传输的字节。如果 event.lengthComputable 不为真,则 event.total 等于0。
与 progress 事件相关的,还有其他五个事件,可以分别指定回调函数:
* load 事件:传输成功完成。
* abort 事件:传输被用户取消。
* error 事件:传输中出现错误。
* loadstart 事件:传输开始。
* loadEnd 事件:传输结束,但是不知道成功还是失败。
十、阅读材料
1. Introduction to XMLHttpRequest Level 2: 新功能的综合介绍。
2. New Tricks in XMLHttpRequest 2:一些用法的介绍。
3. Using XMLHttpRequest:一些高级用法,主要针对 Firefox 浏览器。
4. HTTP Access Control:CORS 综述。
5. DOM access control using cross-origin resource sharing:CORS 的 9 种 HTTP 头信息
6. Server-Side Access Control:服务器端 CORS 设置。
7. Enable CORS:服务端 CORS 设置。
最早,微软在 IE 5 引进了这个接口。因为它太有用,其他浏览器也模仿部署了,ajax 操作因此得以诞生。
但是,这个接口一直没有标准化,每家浏览器的实现或多或少有点不同。HTML 5 的概念形成后,W3C 开始考虑标准化这个接口。2008年 2 月,就提出了 XMLHttpRequest Level 2 草案。
这个 XMLHttpRequest 的新版本,提出了很多有用的新功能,将大大推动互联网革新。本文就对这个新版本进行详细介绍。
一、老版本的 XMLHttpRequest 对象
在介绍新版本之前,我们先回顾一下老版本的用法。
首先,新建一个 XMLHttpRequest 的实例。
var xhr = new XMLHttpRequest ();
然后,向远程主机发出一个 HTTP 请求。
xhr.open ('GET', 'example.php'); xhr.send ();
接着,就等待远程主机做出回应。这时需要监控 XMLHttpRequest 对象的状态变化,指定回调函数。
xhr.onreadystatechange = function (){ if ( xhr.readyState == 4 && xhr.status == 200 ) { alert ( xhr.responseText ); } else { alert ( xhr.statusText ); } };
上面的代码包含了老版本 XMLHttpRequest 对象的主要属性:
* xhr.readyState:XMLHttpRequest 对象的状态,等于 4 表示数据已经接收完毕。
* xhr.status:服务器返回的状态码,等于 200 表示一切正常。
* xhr.responseText:服务器返回的文本数据
* xhr.responseXML:服务器返回的 XML 格式的数据
* xhr.statusText:服务器返回的状态文本。
二、老版本的缺点
老版本的 XMLHttpRequest 对象有以下几个缺点:
* 只支持文本数据的传送,无法用来读取和上传二进制文件。
* 传送和接收数据时,没有进度信息,只能提示有没有完成。
* 受到"同域限制"(Same Origin Policy),只能向同一域名的服务器请求数据。
三、新版本的功能
新版本的 XMLHttpRequest 对象,针对老版本的缺点,做出了大幅改进。
* 可以设置 HTTP 请求的时限。
* 可以使用 FormData 对象管理表单数据。
* 可以上传文件。
* 可以请求不同域名下的数据(跨域请求)。
* 可以获取服务器端的二进制数据。
* 可以获得数据传输的进度信息。
下面,我就一一介绍这些新功能。
四、HTTP 请求的时限
有时,ajax 操作很耗时,而且无法预知要花多少时间。如果网速很慢,用户可能要等很久。
新版本的 XMLHttpRequest 对象,增加了 timeout 属性,可以设置 HTTP 请求的时限。
xhr.timeout = 3000;
上面的语句,将最长等待时间设为 3000 毫秒。过了这个时限,就自动停止 HTTP 请求。与之配套的还有一个 timeout 事件,用来指定回调函数。
xhr.ontimeout = function (event){ alert ('请求超时!'); }
目前,Opera、Firefox 和 IE 10 支持该属性,IE 8 和 IE 9 的这个属性属于 XDomainRequest 对象,而 Chrome 和 Safari 还不支持。
五、FormData 对象
ajax 操作往往用来传递表单数据。为了方便表单处理,HTML 5 新增了一个 FormData 对象,可以模拟表单。
首先,新建一个 FormData 对象。
var formData = new FormData ();
然后,为它添加表单项。
formData.append ('username', '张三'); formData.append ('id', 123456);
最后,直接传送这个 FormData 对象。这与提交网页表单的效果,完全一样。
xhr.send (formData);
FormData 对象也可以用来获取网页表单的值。
var form = document.getElementById ('myform');var formData = new FormData (form); formData.append ('secret', '123456'); // 添加一个表单项 xhr.open ('POST', form.action); xhr.send (formData);
六、上传文件
新版 XMLHttpRequest 对象,不仅可以发送文本信息,还可以上传文件。
假定 files 是一个"选择文件"的表单元素(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);
七、跨域资源共享(CORS)
新版本的 XMLHttpRequest 对象,可以向不同域名的服务器发出 HTTP 请求。这叫做"跨域资源共享"(Cross-origin resource sharing,简称 CORS)。
使用"跨域资源共享"的前提,是浏览器必须支持这个功能,而且服务器端必须同意这种"跨域"。如果能够满足上面的条件,则代码的写法与不跨域的请求完全一样。
xhr.open ('GET', 'http://other.server/and/path/to/script');
目前,除了 IE 8 和 IE 9,主流浏览器都支持 CORS,IE 10 也将支持这个功能。服务器端的设置,请参考《Server-Side Access Control》。
八、接收二进制数据(方法A:改写 MIMEType)
老版本的 XMLHttpRequest 对象,只能从服务器取回文本数据(否则它的名字就不用 XML 起首了),新版则可以取回二进制数据。
这里又分成两种做法。较老的做法是改写数据的 MIMEType,将服务器返回的二进制数据伪装成文本数据,并且告诉浏览器这是用户自定义的字符集。
xhr.overrideMimeType ("text/plain; charset=x-user-defined");
然后,用 responseText 属性接收服务器返回的二进制数据。
var binStr = xhr.responseText;
由于这时,浏览器把它当做文本数据,所以还必须再一个个字节地还原成二进制数据。
for (var i = 0, len = binStr.length; i < len; ++i) { var c = binStr.charCodeAt (i); var byte = c & 0xff; }
最后一行的位运算"c & 0xff",表示在每个字符的两个字节之中,只保留后一个字节,将前一个字节扔掉。原因是浏览器解读字符的时候,会把字符自动解读成 Unicode 的 0xF700-0xF7ff 区段。
八、接收二进制数据(方法B:responseType 属性)
从服务器取回二进制数据,较新的方法是使用新增的 responseType 属性。如果服务器返回文本数据,这个属性的值是"TEXT",这是默认值。较新的浏览器还支持其他值,也就是说,可以接收其他格式的数据。
你可以把 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 Uint8Array (arrayBuffer); for (var i = 0; i < byteArray.byteLength; i++) { // do something } }
更详细的讨论,请看 Sending and Receiving Binary Data。
九、进度信息
新版本的 XMLHttpRequest 对象,传送数据的时候,有一个 progress 事件,用来返回进度信息。
它分成上传和下载两种情况。下载的 progress 事件属于 XMLHttpRequest 对象,上传的 progress 事件属于 XMLHttpRequest.upload 对象。
我们先定义 progress 事件的回调函数。
xhr.onprogress = updateProgress; xhr.upload.onprogress = updateProgress;
然后,在回调函数里面,使用这个事件的一些属性。
function updateProgress (event) { if (event.lengthComputable) { var percentComplete = event.loaded / event.total; } }
上面的代码中,event.total 是需要传输的总字节,event.loaded 是已经传输的字节。如果 event.lengthComputable 不为真,则 event.total 等于0。
与 progress 事件相关的,还有其他五个事件,可以分别指定回调函数:
* load 事件:传输成功完成。
* abort 事件:传输被用户取消。
* error 事件:传输中出现错误。
* loadstart 事件:传输开始。
* loadEnd 事件:传输结束,但是不知道成功还是失败。
十、阅读材料
1. Introduction to XMLHttpRequest Level 2: 新功能的综合介绍。
2. New Tricks in XMLHttpRequest 2:一些用法的介绍。
3. Using XMLHttpRequest:一些高级用法,主要针对 Firefox 浏览器。
4. HTTP Access Control:CORS 综述。
5. DOM access control using cross-origin resource sharing:CORS 的 9 种 HTTP 头信息
6. Server-Side Access Control:服务器端 CORS 设置。
7. Enable CORS:服务端 CORS 设置。
相关文章推荐
- XMLHttpRequest Level 2 使用指南——ajax实现http(s)协议的原理
- 【Ajax】------XMLHttpRequest Level 2 使用指南
- Ajax学习(三)——XMLHttpRequest对象的五步使用法
- AJAX——核心XMLHttpRequest对象
- XMLHttpRequest 对象(AJAX)的状态码(readyState)及HTTP 状态代码(status)的对照表
- AJAX——核心XMLHttpRequest对象
- Ajax 中 XMLHttpRequest对象的方法与属性
- ajax——XMLHttpRequest
- XMLHttpRequest Level 2的简单例子
- ASP.NET MVC中使用AJAX(XMLHttpRequest、Microsoft AJAX Library......)
- 使用xmlHttpRequest实现Ajax技术
- 1次ajax请求(XMLHttpRequest)上传多个文件,支持进度条
- 【Ajax 2】封装Ajax的核心对象:XMLHttpRequest对象
- Ajax 中的xmlHttpRequest.open对url的处理
- Ajax简单应用示例: XMLHttpRequest对象实例化方式及调用
- XMLHttpRequest Level 2 使用指南
- AJAX(二)--核心对象XMLHttpRequest
- XMLHttpRequest 对象--AJAX的基础 .
- ajax原理和XmlHttpRequest对象
- Ajax入门之XMLHttpRequest核心对象的详解