XHR 对象的用法
var xhr = new XMLHttpRequest();
open
使用 XHR 对象时,调用的第一个方法就是 open(),他接受 3 个参数:要发送的请求的类型("get", "post" 等)、 请求的 URL 和表示是否异步发送请求的布尔值。
·
// get 方法, 请求 "example.php", 同步发送请求 xhr.open("get", "example.php", false);
两个注意点:
- URL 相对于执行代码的当前页面(当然也可以使用绝对路径);
- 调用 open() 方法并不会真正发送请求,而只是启动一个请求以备发送;
send
// send 方法只接收一个参数,即要作为请求主题发送的数据。如果不通过请求主体发送数据,则必须传入 null,因为这个参数对有些浏览器是必须的。 xhr.send(null);
调用 send 之后,请求就会被派发到服务器;
接收到响应后
在收到响应后,响应的数据会自动填充 XHR 对象的属性。
- responseText: 作为响应主体被返回的文本;
- responseXML: 如果响应的内容类型是“text/xml”或“application/xml”,这个属性将保存包含着响应数据的 XML DOM 文档;
- status: 响应的 HTTP 状态;
- statusText: HTTP 状态的说明
XHR 对象的 readyState 属性
该属性表示请求/响应过程的当前活动阶段,可以取如下这些值:
0: 未初始化,尚未调用 open() 方法;
1: 启动。已经调用 open() 方法,但是还未调用 send() 方法;
2. 发送。已经调用 send() 方法,但尚未接收到响应;
3. 接收。已经接收到部分响应数据;
4. 完成。已经接收到全部响应数据,而且已经可以在客户端使用了;
只要 readyState 属性的值由一个值变成另一个值,都会触发一次 readyStatechange 事件。
var xhr = new XMLHttpRequest(); xhr.onreadystatechange =function(){ if(xhr.readyState === 4){ if((xhr.status >= 200 && xhr.status < 300) || (xhr.status === 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful:" + xhr.status); } } }; xhr.open("get", "example.com", true); xhr.send(null);
XHR 操纵 HTTP 头部信息
常见的 header
- Accept: 浏览器能够处理的内容类型;
- Accept-Charset: 浏览器能够显示的字符集;
- Accept-Encoding: 浏览器能够处理的压缩编码;
- Accept-Language: 浏览器当前设置的语言;
- Connection: 浏览器与服务器之间连接的类型;
- Cookie: 当前页面设置的 Cookie;
- Host: 发出请求的页面所在的域;
- Referer: 发出请求的页面的 URI。
- User-Agent: 浏览器的用户代理字符串;
setRequestHeader
setRequestHeader 方法可以设置自定义的请求头部信息。这个方法接受两个参数:头部字段的名称和头部字段的值。
要成功发送请求头部信息,必须在调用 open() 方法之后,调用 send() 方法之前调用 setRequestHeader()
var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if(xhr.readyState === 4){ if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){ alert(xhr.responseText); } else { alert('error'); } } }; xhr.open("get", "example.php", true); xhr.setRequestHeader("MyHeader", "MyValue"); xhr.send(null);
p.s 与 get 请求相比,post 请求消耗的资源会更多一些。从性能角度来看,以发送相同的数据统计,get 请求的速度最多可达到 post 请求的两倍。
XMLHttpRequest 2级
老版本的 XMLHttpRequest 对象有以下几个缺点:
- 只支持文本数据的传输,无法用来读取和上传二进制文件;
- 传送和接受数据时,没有进度信息,只能提示有没有完成;
- 受到“同域限制”,只能向同一域名的服务器请求数据;
新版本的功能
- 可以设置 http 请求的时限;
- 可以使用 FormData对象管理表单数据;
- 可以上传文件;
- 可以请求不同域名下的数据(跨域请求)
- 可以获取服务器端的二进制数据;
- 可以获取数据传输的进度信息;
FormData
var data = new FormData(); data.append("name", "Nicholas"); // 也可以传入表单元素 var data = new FormData(document.forms[0]); xhr.send(data);
使用 FormData 的方便之处体现在不必明确地在 XHR 对象上设置请求头部。XHR 对象能够识别传入的数据类型是 FormData 的实例,并配置适当的头部信息。
超时设定
timeout 属性表示请求在等待响应多少毫秒之后就会终止。在给 timeout 设置一个数值后,如果在规定的时间内浏览器还没有接收到响应,那么就会触发 timeout 事件,进而会调用 ontimeout 事件处理程序。
var xhr = new XMLHttpRequest(); xhr.onreadystatechange = function () { if(xhr.readyState === 4){ if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304){ alert(xhr.responseText); } else { alert('error'); } } }; xhr.open("get", "example.php", true); xhr.timeout = 1000; xhr.ontimeout = function(){ alert("Request did not return in a second."); } xhr.setRequestHeader("MyHeader", "MyValue"); xhr.send(null);
overrideMimeType() 方法
该方法用于重写 XHR 响应的 MIME 类型。因为返回的 MIME 类型决定了 XHR 对象如何处理它,所以提供一种方法能够重写服务器返回的 MIME 类型是很有用的。
var xhr = new XMLHttpRequest(); xhr.open("get", "text.php", true); xhr.overrideMimeType("text/xml"); xhr.send(null);
进度信息
传送数据的时候,有一个 progress 事件,用来返回进度信息。
它分为上传和下载两种情况。下载的 progress 事件属于 XMLHttpRequest 对象,上传的 progress 对象属于 XMLHttpRequest.upload 对象。
xhr.onprogress = updateProgress; xhr.upload.onprogress = updateProgress;
function updateProgress(event) { if (event.lengthComputable) { var percentComplete = event.loaded / event.total; } }
与 progress 事件相关的,还有其他5个事件,可以分别指定回调函数:
- load: 传输成功完成;
- abort: 传输被用户取消;
- error: 传输中出现错误;
- loadStart: 传输开始;
- loadEnd: 传输结束,但是不知道成功还是失败;