JavaScirpt 中的 XMLHttpRequest 对象用于与服务器进行数据交互,可用来发送或者接受服务器数据。所有现代的浏览器都支持 XMLHttpRequest 对象。 XMLHttpRequest 对象用途广泛,其用途包括:在不重新加载页面的情况下更新网页、在页面已加载后从服务器请求数据、在页面已加载后从服务器接收数据、向后台服务器发送数据等。

创建 XMLHttpRequest 对象

目前主流浏览器支持 XMLHttpRequest 对象,唯一的浏览器依赖性涉及XMLHttpRequest 对象的创建。所有现代浏览器( IE7+、Firefox、Chrome、Safari 以及 Opera)都内建了 XMLHttpRequest 对象,在 IE 5 和 IE 6 中可以使用IEActiveXObject() 的构造函数。因此,创建 XMLHttpRequest 对象可以采用如下方法:

var xhr = null;
if (window.XMLHttpRequest)
{
     // 主流浏览器创建对象
     xhr = new XMLHttpRequest();
}
else if (window.ActiveXObject)
{
    //IE5、6创建对象
    xhr = new ActiveXObject("Microsoft.XMLHTTP");
}

XMLHttpRequest 对象属性

readyState

HTTP 请求的状态。当用 XMLHttpRequest 对象发起 HTTP 请求时,readyState 会从 0(初始化)递增到 4(接收完成)。 readyState 只会递增,不会减少,除非当一个请求在处理过程中的时候调用了 abort() 或 open() 方法。每次这个属性的值增加的时候,都会触发 onreadystatechange 事件监听。5种状态说明如下:

状态名称说明
0Uninitialized初始化。XMLHttpRequest对象已创建或已被abort()方法重置
1Openopen() 方法已调用,但是 send() 方法未调用。请求还没有被发送
2Sentsend()方法已调用,HTTP请求已发送到Web服务器。但还未接收到响应
3Receiving所有响应头部都已经接收到。响应体开始接收但未完成
4LoadedHTTP响应已经完全接收

responseText

接收到的服务器的响应结果(不包括HTTP头信息)。当 readyState 小于 3 时,此属性是一个空字符串。当 readyState 为 3 时,这个属性为已经接收的部分响应内容。当 readyState 为 4 时,这个属性为完整的响应结果。

responseXML

与 responseText 类似,接收到的服务器的响应结果,但解析为 XML 并作为Document 对象返回,可以使用 W3C DOM 节点树方法和属性对该 XML 文档对象进行检查和解析。

status

服务器返回的 HTTP 状态代码,例如:200 响应正常、404 表示页面未找到。当 readyState 小于 3 时,此属不存在,读取这一属性会抛出一个异常。

statusText

服务器返回的 HTTP 状态名,即:状态码对应的名称。例如:当状态为 200 的时候其值为"OK",当状态为 404 的时候其值是"Not Found"。和 status 属性一样,当 readyState 小于 3时,此属不存在,读取这一属性会抛出一个异常。

XMLHttpRequest 对象事件监听

onreadystatechange

每次 readyState 属性改变的时,调用的监听事件。当 readyState 为 3(所有响应头部都已经接收到。响应体开始接收但未完成时,此监听可能会被调用多次。

XMLHttpRequest 对象方法

abort()

重置当前请求的响应,关闭连接并且结束任何未完成的网络活动。
说明:此方法会把把 XMLHttpRequest 对象 readyState 属性值,重置为 0(初始化状态),并且取消所有完成的网络活动。如果请求用的时间较长,而且响应不再必要的时候,可以调用这个方法。

getAllResponseHeaders()

把 HTTP 响应头作为未解析的字符串返回。
说明:如果 readyState 小于 3,这个方法返回 null。否则,它返回服务器发送的所有 HTTP 响应头。响应头部作为单个的字符串返回,一行一个头部。每行用换行符 "\r\n" 隔开。

getResponseHeader()

返回指定的 HTTP 响应头的值。其参数是要返回的 HTTP 响应头部的名称。可以使用任何大小写来制定这个头部名字,和响应头部的比较是不区分大小写的。
说明:如果没有接收到这个头部或者 readyState 小于 3 则为空字符串。如果接收到多个有指定名称的头部,这个头部的值被连接起来并返回,使用逗号和空格分隔开各个头部的值。

open(method, url, async, username, password)

初始化 HTTP 请求参数,例如 URL 和 HTTP 方法,但是并不发送请求。
参数说明
method:参数是用于请求的 HTTP 方法。值包括 GET、POST 和 HEAD。
url:参数是请求的主体。大多数浏览器实施了一个同源安全策略,并且要求这个 URL 与包含脚本的文本具有相同的主机名和端口。
async:参数指示请求使用应该异步地执行。如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄。
username 和 password:这两个参数是可选的,为 url 所需的授权提供认证资格。

调用说明
open() 方法用于初始化请求参数,初始化的参数将在其后调用的send()方法中使用。
此方法会把readyState设置为1,删除之前指定的所有请求头部,以及之前接收的所有响应头部,并且把 responseText、responseXML、status 以及 statusText 参数设置为它们的默认值。
当 readyState 为 0 的时候(当 XMLHttpRequest 对象刚创建或者 abort() 方法调用后)以及当 readyState 为 4 时(已经接收响应时),调用这个方法是安全的。
除了为 send() 方法准备请求参数和重置 XMLHttpRequest 对象以便复用,open()法没有其他行为。
需要特别注意的是,当这个方法调用的时候,是不会打开一个到 Web 服务器的网络连接的。

send(body)

发送 HTTP 请求。使用传递给 open() 方法的参数,向 web 服务器发送 HTTP 请求。
说明:
如果通过 open() 指定的 HTTP 方法是 POST或 PUT,body 参数指定了请求体,请求体为一个字符串或者 Document 对象。如果没有请求体的,这个参数就为 null。
这个方法会发送一个HTTP 请求。如果之前没有调用 open(),即:readyState不是 1,send() 抛出一个异常。
HTTP 请求由以下几部分组成:
调用 open() 方法指定的 HTTP 方法、URL 以及认证资格(如果有的话)。
调用setRequestHeader()方法时设定的HTTP请求头信息如果有的话)。
传递给这个方法的 body 参数。

HTTP 请求过程
HTTP 请求发送后,send() 会把 readyState 设置为2,并触发 onreadystatechange 事件临听。
如果通过 open() 方法设置 async 参数为 false ,这个方法会阻塞并不会返回,直到readyState为 4 并且服务器的响应被完全接收才会相应。如果为 true 或者省略此参数时,send() 立即返回,服务器响应会在一个后台线程中处理。
如果服务器响应带有 HTTP 重定向,send() 方法或后台线程自动进行重定向。
当所有的 HTTP 响应头部已经接收,send() 或后台线程把 readyState 设置为 3 并触发 onreadystatechange 事件监听。如果响应较长,send() 或后台线程可能会多次在状态 3 中触发 onreadystatechange 事件监听(此特性可以作为一个下载进度指示器)。
最后,当响应完成,send() 或后台线程把 readyState 设置为 4,并最后一次触发事件监听。

setRequestHeader(name, value)

向一个打开但未发送的请求设置或添加一个 HTTP 请求。
参数说明
name:要设置的HTTP请求头的名称(此参数不能为空白、冒号或换行)。
value:要设置HTTP请求头的值(此参数不能为换行)。

说明
setRequestHeader()方法用于设置HTTP请求的头信息,此方法的设置会被添加到send()方法创建的请求中。
这个方法只有当 readyState 为 1 的时候才能调用。即:在调用了 open() 之后,且在调用 send() 之前调用。
如果指定HTTP头信息已经指定了,这个头信息对应的新值就是:之前指定的值,加上逗号、空白以及这个新指定的值。
setRequestHeader()方法可以用来设置HTTP请求头包括:Authorization、cookie、User-Agent等。
有些请求头部由 XMLHttpRequest 自动设置而不是由这个方法设置,以符合 HTTP 协议。XMLHttpRequest自动设置的请求头有:Host、Connection、Keep-Alive、Accept-charset、Accept-Encoding、If-Modified-Since、If-None-Match、If-Range、Range

使用示例

使用 XMLHttpRequest 对象访问天真的小窝的首页:https://bin.zmide.com,将请求结果显示到 id 为 resp 的 div 标签中。JS代码如下

var xhr = new XMLHttpRequest();
xhr.open("GET", "https://bin.zmide.com", true);
xhr.onreadystatechange = function() {
  if (xhr.readyState == 4) {
   // 显示请求结果
    document.getElementById("resp").innerHTML = xhr.responseText;
    console.log(xhr.responseXML);
  }
}
xhr.send();

特别说明: XmlHttpRequest 不支持跨域访问,这是由网景公司 ( netscape ) 在开发浏览器时定义的同源策略导致的。( 解决办法就是弄个 php 转发一下接口 )