XMLHttpRequest

XMLHttpRequest (XHR) 是一个 JavaScript类，包含将HTTP请求从网络浏览器异步传输到网络服务器的方法。这些方法允许基于浏览器的应用程序进行细粒度的服务器调用并把存储结果存储在XMLHttpRequest的responseText特性中。 XMLHttpRequest类是Ajax编程的一个组件。在Ajax出现之前，需要将网页表单完全发送到服务器，然后刷新整个浏览器页面。

历史
“XMLHttpRequest”类背后的概念是由Microsoft Outlook 的开发人员于2000年提出的——可在Windows 2000操作系统上使用。然后这个概念在Internet Explorer 5 (2001) 浏览器的 解释器 中实现。但是，原始的语法没有使用XMLHttpRequest标识符。相反，开发人员使用了标识符ActiveXObject("Msxml2.XMLHTTP")和ActiveXObject("Microsoft.XMLHTTP")。 到Internet Explorer 7 (2006)，所有的浏览器都支持XMLHttpRequest标识符。

XMLHttpRequest标识符现在是所有现代浏览器的事实标准，包括Mozilla的Gecko layout engine (2002), Konqueror (2002), Safari 1.2 (2004), Opera 8.0 (2005),, and iCab (2005).

随着跨浏览器 JavaScript 库（例如 jQuery）的出现，开发人员可以间接调用 XMLHttpRequest 功能。

标准
万维网联盟 (W3C)于2006年4月5日发布了XMLHttpRequest对象的工作草案规范。 2008年2月25日，W3C发布了Working Draft Level 2规范。Level 2规范添加了监视事件进度、允许跨站点请求和处理字节流的方法。2011年底，Level 2规范被吸收到原始规范中。

2012年底，WHATWG接管开发并使用Web IDL维护动态文档。
XMLHttpRequest用法

构造器
生成发给Web服务器的异步请求首先要实例化分配内存）“XMLHttpRequest”对象。分配的内存（的地址）被赋值给变量。 JavaScript中实例化新对象的编程 语句 为new。new语句后跟对象的构造函数。面向对象语言的开发人员的习惯是使用与类名相同的名称来调用构造函数本例中，类名是XMLHttpRequest。实例化一个新的XMLHttpRequest并赋值给变量request:

var request = new XMLHttpRequest();

open方法
open方法准备XMLHttpRequest。它最多可接受五个参数，但只有前两个是必须的。

var request = new XMLHttpRequest();

request.open( RequestMethod, SubmitURL, AsynchronousBoolean, UserName, Password );

 RequestMethod: 对于典型的数据量，HTTP请求方法可以是GET。在其他可用的请求方法中，POST将处理大量数据。收到返回字符串后，将DELETE请求方法发送到.open()以释放 XMLHttpRequest 内存。如果发送DELETE，则 SubmitURL 参数可为null。
 * request.open( "DELETE", null );
 SubmitURL: SubmitURL是包含执行文件名和提交到Web服务器的任何参数的URL。如果URL包含主机名，则它一定是发送HTML文档的Web服务器。Ajax支持同源策略。
 AsynchronousBoolean: 如果提供该参数，则应将其设置为true。如果设置为false，则浏览器将等待，直到收到返回字符串。不鼓励程序员将AsynchronousBoolean设置为false，浏览器可能会遇到异常错误。
 UserName:如果提供，它将有助于验证用户身份。
 Password: 如果提供，它将有助于验证用户身份。

setRequestHeader方法
如果调用POST请求方法，则需要额外发送媒体类型Content-Type: application/x-www-form-urlencoded。setRequestHeader方法允许程序将此或其他HTTP标头发送到Web服务器。其用法是setRequestHeader( HeaderField, HeaderValue )。启用POST请求方法:

request.setRequestHeader( "Content-Type", "application/x-www-form-urlencoded" );

send方法
如果调用POST请求方法，则Web服务器期望从标准输入流读取表单数据。要将表单数据发送到Web服务器，请执行request.send( FormData )，其中FormData是文本字符串。如果调用GET请求方法，则Web服务器只需要默认标头。要发送默认标头，请执行request.send( null ). 
onreadystatechange事件监听器
onreadystatechange是一个回调方法，在整个Ajax生命周期中定期执行。要设置名为 ReadyStateMethod()的回调方法，语法为request.onreadystatechange = ReadyStateMethod。为了方便起见，该语法允许定义匿名方法。定义匿名回调方法:
var request = new XMLHttpRequest();

request.onreadystatechange = function()
{
// code omitted
}
XMLHttpRequest生命周期经历几个阶段 - 从0到4。阶段0是调用open()方法之前，阶段4是文本字符串到达时。为了监视生命周期，XMLHttpRequest具有可用的readyState属性。 第1-3阶段不明确，不同浏览器的解释也不同。尽管如此，一种解释是：
 阶段 0：未初始化
 第一阶段：加载中
 第二阶段：加载完成
 第三阶段：交互
 第四阶段：已完成

当readyState达到4时，文本字符串已经到达并被设置在responseText属性中。
var request = new XMLHttpRequest();

request.onreadystatechange = function()
{
    if ( request.readyState == 4 )
    {
        // request.responseText is set
    }
}

例子
下例首先创建Javascript函数:

 cd /var/www/html
 编辑文件ajax_submit.js:

function ajax_submit( element_id, submit_url )
{
    var request = new XMLHttpRequest();
    var completed_state = 4;

    request.onreadystatechange = function()
    {
        if ( request.readyState == completed_state )
        {
            document.
                getElementById( element_id ).
                innerHTML =
                    request.responseText;
            request.open( "DELETE", null );
        }
    }

    request.open( "GET", submit_url );
    request.send( null );
}

 同一个目录下编辑文件ajax.phtml:
<?php
    echo '<h1>Hello World!</h1>';
?>

 同一个目录下编辑文件ajax.html:
<html>
<head>
    <title>Hello World</title>
    <script type=text/javascript src=ajax_submit.js></script>
</head>
<body>
    <div id=ajax_title></div>
    <button onclick="ajax_submit( 'ajax_title', 'ajax.phtml' )">
        Submit
    </button>
</body>

 在浏览器中打开http://localhost/ajax.html
 点击Submit

CGI例子
通用网关接口 (CGI) 进程允许浏览器请求Web服务器执行已编译的计算机程序。

CGI XMLHttpRequest的服务器组件是位于服务器上的可执行文件。操作系统将打开该文件并读取其机器指令。 XMLHttpRequest协议要求可执行文件输出文本字符串。

编译后的程序有两个文件：源代码和相应的可执行文件。

 cd /usr/lib/cgi-bin
 编辑文件ajax.c:
#include <stdio.h>

void main( void )
{
    /* CGI requires the first line to output: */
    printf( "Content-type: text/html\n" );

    /* CGI requires the second line to output: */
    printf( "\n" );

    printf( "<h1>Hello World!</h1>\n" );
}

 编辑源文件产生可执行文件:
cc ajax.c -o ajax

或

sudo cc ajax.c -o ajax

CGI浏览器组件与PHP浏览器组件相同，只是submit_url略有变化。 告诉Web服务器执行可执行文件的语法是/cgi-bin/后跟文件名。为了安全起见，可执行文件必须驻留在chroot 监狱中。在本例中，监狱是目录/usr/lib/cgi-bin/.

  cd /var/www/html
 编辑文件ajax.html:
<html>
<head>
    <title>Hello World</title>
    <script type=text/javascript src=ajax_submit.js></script>
</head>
<body>
    <div id=ajax_title></div>
    <button onclick="ajax_submit( 'ajax_title', '/cgi-bin/ajax' )">
        Submit
    </button>
</body>

 用浏览器打开http://localhost/ajax.html
 点击Submit

参见
 WebSocket
 表现层状态转换 (REST)

参考文献

注释

外部链接

 XMLHttpRequest Living Standard  by the WHATWG
 XMLHttpRequest Level 1  draft by the W3C

Category:XML
Category:微軟API 
Category:JavaScript  
Category:网页标准
Category:2000年软件
Category:HTTP客户端
Category:AJAX