XMLHttpRequest

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

历史

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

XMLHttpRequest标识符现在是所有现代浏览器的事实标准,包括MozillaGecko layout engine (2002), Konqueror (2002), Safari 1.2 (2004),[5] Opera 8.0 (2005),[6], and iCab (2005).[7]

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

标准

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

2012年底,WHATWG接管开发并使用Web IDL维护动态文档[11]

XMLHttpRequest用法

构造器

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

var request = new XMLHttpRequest();[14]

open方法

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

var request = new XMLHttpRequest();

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

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

setRequestHeader方法

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

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

send方法

如果调用POST请求方法,则Web服务器期望从标准输入流读取表单数据[21]要将表单数据发送到Web服务器,请执行request.send( FormData ),其中FormData是文本字符串。如果调用GET请求方法,则Web服务器只需要默认标头。[22]要发送默认标头,请执行request.send( null ).[d]

onreadystatechange事件监听器

onreadystatechange是一个回调方法,在整个Ajax生命周期中定期执行。[23]要设置名为 ReadyStateMethod()的回调方法,语法为request.onreadystatechange = ReadyStateMethod[e]为了方便起见,该语法允许定义匿名方法。[23]定义匿名回调方法:

var request = new XMLHttpRequest();

request.onreadystatechange = function()
{
// code omitted
}

XMLHttpRequest生命周期经历几个阶段 - 从0到4。阶段0是调用open()方法之前,阶段4是文本字符串到达时。[22]为了监视生命周期,XMLHttpRequest具有可用的readyState属性。 第1-3阶段不明确,不同浏览器的解释也不同。[15]尽管如此,一种解释是:[15]

  • 阶段 0:未初始化
  • 第一阶段:加载中
  • 第二阶段:加载完成
  • 第三阶段:交互
  • 第四阶段:已完成

readyState达到4时,文本字符串已经到达并被设置在responseText属性中。

var request = new XMLHttpRequest();

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

例子

下例首先创建Javascript函数[22]:

  • 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>

CGI例子

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

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/.[g]

  • 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>

参见

参考文献

  1. ^ Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 92. ISBN 978-0-596-10180-0. Javascript lacks a portable mechanism for general network communication[.] ... But thanks to the XMLHttpRequest object, ... Javascript code can make HTTP calls back to its originating server[.] 
  2. ^ 2.0 2.1 Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 92. ISBN 978-0-596-10180-0. 
  3. ^ Article on the history of XMLHTTP by an original developer. Alexhopmann.com. 2007-01-31 [2009-07-14]. (原始内容存档于2009-01-30). The reality is that the client architecture of GMail appears to follow the rough design of the Exchange 2000 implementation of Outlook Web Access for IE5 and later which shipped way back in 2000. 
  4. ^ 4.0 4.1 Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 93. ISBN 978-0-596-10180-0. 
  5. ^ Archived news from Mozillazine stating the release date of Safari 1.2. Weblogs.mozillazine.org. [2009-07-14]. (原始内容存档于2009-06-02). 
  6. ^ Press release stating the release date of Opera 8.0 from the Opera website. Opera.com. 2005-04-19 [2009-07-14]. (原始内容存档于2009-01-20). 
  7. ^ Soft-Info.org. Detailed browser information stating the release date of iCab 3.0b352. Soft-Info.com. [2009-07-14]. (原始内容存档于2011-07-25). 
  8. ^ Specification of the XMLHttpRequest object from the Level 1 W3C Working Draft released on April 5th, 2006. W3.org. [2009-07-14]. (原始内容存档于2008-05-16). 
  9. ^ Specification of the XMLHttpRequest object from the Level 2 W3C Working Draft released on February 25th, 2008. W3.org. [2009-07-14]. (原始内容存档于2023-04-01). 
  10. ^ XMLHttpRequest Editor's Draft 5 December 2011. w3.org. [5 December 2011]. (原始内容存档于2019-03-23). 
  11. ^ XMLHttpRequest Standard/#specification-history. [2023-10-17]. (原始内容存档于2023-11-08). 
  12. ^ Flanagan, David. JavaScript, The Definitive Guide. O'Reilly and Associates. 1998: 82. ISBN 1-56592-392-8. 
  13. ^ Welling, Luke; Thomson, Laura. PHP and MySQL Web Development. Sams Publishing. 2005: 162. ISBN 0-672-32672-8. 
  14. ^ XMLHttpRequest Standard; The constructor. [2023-04-10]. (原始内容存档于2023-11-08). 
  15. ^ 15.0 15.1 15.2 15.3 Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 100. ISBN 978-0-596-10180-0. 
  16. ^ Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 96. ISBN 978-0-596-10180-0. 
  17. ^ HTTP Documentation. June 2022 [2023-04-12]. (原始内容存档于2023-10-03). 
  18. ^ Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 98. ISBN 978-0-596-10180-0. 
  19. ^ XMLHttpRequest Standard; The open method. [2023-04-12]. (原始内容存档于2023-11-08). 
  20. ^ Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 97. ISBN 978-0-596-10180-0. 
  21. ^ Flanagan, David. JavaScript, The Definitive Guide. O'Reilly and Associates. 1998: 511. ISBN 1-56592-392-8. 
  22. ^ 22.0 22.1 22.2 Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 26. ISBN 978-0-596-10180-0. 
  23. ^ 23.0 23.1 Mahemoff, Michael. Ajax Design Patterns. O'Reilly. 2006: 25. ISBN 978-0-596-10180-0. 
  24. ^ 24.0 24.1 Apache Tutorial. [2023-04-10]. (原始内容存档于2021-11-15). 

注释

  1. ^ 尽管一些文献 XMLHttpRequest 称为API, 从技术上讲,它是一个使用 new语句实例化对象变量的类声明.
  2. ^ 现代浏览器使用即时编译器调用了JavaScript引擎
  3. ^ 该标准是Opera SoftwareAnne van Kesteren和W3C的Dean Jackson审稿
  4. ^ The null placeholder is currently in retirement but recommended.
  5. ^ For safety, this assignment should follow the execution of request.open().
  6. ^ The web server may be configured to execute interpreted programs, also.[24]
  7. ^ The web server may be configured to add other executable directories.[24]

外部链接