XHR 对象的用法

var xhr = new XMLHttpRequest();

open

使用 XHR 对象时,调用的第一个方法就是 open(),他接受 3 个参数:要发送的请求的类型("get", "post" 等)、 请求的 URL 和表示是否异步发送请求的布尔值。
·

// get 方法, 请求 "example.php", 同步发送请求
xhr.open("get", "example.php", false);

两个注意点:

  1. URL 相对于执行代码的当前页面(当然也可以使用绝对路径);
  2. 调用 open() 方法并不会真正发送请求,而只是启动一个请求以备发送;

send

// send 方法只接收一个参数,即要作为请求主题发送的数据。如果不通过请求主体发送数据,则必须传入 null,因为这个参数对有些浏览器是必须的。
xhr.send(null);

调用 send 之后,请求就会被派发到服务器;

接收到响应后

在收到响应后,响应的数据会自动填充 XHR 对象的属性。

  1. responseText: 作为响应主体被返回的文本;
  2. responseXML: 如果响应的内容类型是“text/xml”或“application/xml”,这个属性将保存包含着响应数据的 XML DOM 文档;
  3. status: 响应的 HTTP 状态;
  4. 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

  1. Accept: 浏览器能够处理的内容类型;
  2. Accept-Charset: 浏览器能够显示的字符集;
  3. Accept-Encoding: 浏览器能够处理的压缩编码;
  4. Accept-Language: 浏览器当前设置的语言;
  5. Connection: 浏览器与服务器之间连接的类型;
  6. Cookie: 当前页面设置的 Cookie;
  7. Host: 发出请求的页面所在的域;
  8. Referer: 发出请求的页面的 URI。
  9. 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 对象有以下几个缺点:

  1. 只支持文本数据的传输,无法用来读取和上传二进制文件;
  2. 传送和接受数据时,没有进度信息,只能提示有没有完成;
  3. 受到“同域限制”,只能向同一域名的服务器请求数据;

新版本的功能

  1. 可以设置 http 请求的时限;
  2. 可以使用 FormData对象管理表单数据;
  3. 可以上传文件;
  4. 可以请求不同域名下的数据(跨域请求)
  5. 可以获取服务器端的二进制数据;
  6. 可以获取数据传输的进度信息;

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个事件,可以分别指定回调函数:

  1. load: 传输成功完成;
  2. abort: 传输被用户取消;
  3. error: 传输中出现错误;
  4. loadStart: 传输开始;
  5. loadEnd: 传输结束,但是不知道成功还是失败;