Open toFrankie opened 1 year ago
在 1999 年,微软发布 IE5,第一次引入了新功能:允许 JavaScript 脚本向服务器发起 HTTP 请求。这功能在当时并没有被引起注意,直到 2004 年 Gmail 和 2005 年 Google Map 的发布,才引起广泛的重视。在 2005 年 2 月,Ajax (Asynchronous JavaScript And XML,中文翻译是:异步的 JavaScript 和 XML )这词第一次提出,指围绕这个功能进行开发的一整套做法。此后,Ajax 成为脚本发起 HTTP 通信的代名词,W3C 也在 2006 年发布了它的国际标准。
Asynchronous JavaScript And XML
异步的 JavaScript 和 XML
XHR 是 XMLHttpRequest 的简称。这是微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现。XHR 为向服务器发送请求和解析服务器响应提供了流畅的接口,能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。
XMLHttpRequest
IE5是第一款引入 XHR 对象的浏览器, 在 IE5中, XHR 对象是通过 MSXML 库中的一个 ActiveX 对象实现的,而 IE7+ 及其他标准浏览器都支持原生的 XHR 对象。
let xhr if (window.XMLHttpRequest) { xhr = new window.XMLHttpRequest() } else { // IE5, IE6 xhr = new ActiveXObject('Microsort.XMLHTTP') }
注意:如果要建立 N 个不同的请求,就要使用 N 个不同的 XHR 对象。当然可以重用已存在的 XHR 对象,但这会终止之前通过该对象挂起的任何请求。
发送请求的过程,包括 open 和 send 两个方法。
在使用 XHR 对象时,要调用的第一个方法是 open() ,该方法接收 3 个参数;
open()
// xhr.open(method, url, async) xhr.open('GET', 'example.php', false)
GET
POST
HEAD
OPTIONS
PUT
CONNECT
TRACE
TRACK
true
false
如果接收的是同步响应,则需要将 open() 方法的第三个参数设置为 false,那么 send() 方法将阻塞直到请求完成。 同步请求是吸引人的,但应该避免使用它们。客户端 JavaScript 是单线程的,当 send() 方法阻塞时,他通常会导致整个页面冻结。如果连接的服务器响应慢,那么用户的浏览器看起来像“假死”状态。
如果接收的是同步响应,则需要将 open() 方法的第三个参数设置为 false,那么 send() 方法将阻塞直到请求完成。
send()
同步请求是吸引人的,但应该避免使用它们。客户端 JavaScript 是单线程的,当 send() 方法阻塞时,他通常会导致整个页面冻结。如果连接的服务器响应慢,那么用户的浏览器看起来像“假死”状态。
send() 方法接收一个参数,即要作为请求主体发送的数据。调用 send() 方法后,请求被分派到服务器。
null
xhr.open('GET', 'example.php', false) xhr.send(null)
一个完整的 HTTP 响应由状态码、响应头集合、响应主体组成。在收到响应后,这些都可以通过 XHR 对象的属性和方法使用,主要有以下 4 个属性:
text/xml
application/xml
在接收到响应之后,第一步是检测 status 属性,以确定响应已经成功返回。一般来说,可以将 HTTP状态码为 200 作为成功的标志。此时,responseText 属性的内容已经就绪,而且在内容类型正确的情况下, responseXML 也可以访问了。此外,状态码为 304 表示请求的资源并没有被修改,可以直接使用浏览器中的缓存版本。当然,也意味着响应是有效的。
无论内容类型是什么,响应主体的内容都会保存到 responseText 属性中,而对于非 XML 数据而已,responseXML 属性的值将为 null。
// 这是同步的方式,(异步则需要监听 onreadystatechange 事件,继续往下看) if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { alert(xhr.responseText) } else { alert('request was unsuccessful: ' + xhr.status) }
当发送一个请求后,客户端需要确定这个请求什么时候会完成,因此,XHR 对象提供了 onreadystatechange 事件机制来捕获请求的状态,继而实现响应。
每当 readyState 改变时,就会触发 onreadystatechange 事件。readyState 属性存有 XHR 的状态信息。 readyState 存有 XHR 的状态,从 0 到 4 发生变化。
// 异步方式 xhr.onreadystatechange = function() { if (xhr.readyState === 4 && xhr.status === 200) { alert('request was successful!') } }
注意:理论上,只要 readyState 属性值发生改变,都会触发一次 onreadystatechange 事件。但是为了确保跨浏览器的兼容性,必须在调用 open() 之前指定 onreadystatechange 事件处理程序,否则将无法接收 readyState 属性为 0 和 1 的情况。
readyState
onreadystatechange
0
1
XHR 对象的 timeout 属性等于一个整数,单位毫秒(ms),表示该请求的最大请求时间。即在多少毫秒后,如果请求仍然没有得到结果,就会自动终止。该属性默认为 0,表示没有时间限制。
如果请求超时,将会触发 ontimeout 事件。
xhr.open('POST', 'example.php', true) xhr.ontimeout = function () { console.log('The request timed out') } xhr.timeout = 1000 xhr.send()
IE8 浏览器不支持该属性。
只要弄清楚了整个过程,就会发现其实它并没有那么神秘,对吧。 概而括之,整个 XHR 对象的生命周期应该包括如下阶段:创建 → 初始化请求 → 发送请求 → 接收数据 → 解析数据 → 完成。
// 整个过程 function httpRequest() { let xhr // 创建 xhr 对象 if (window.XMLHttpRequest) { xhr = new window.XMLHttpRequest() } else { // 为了兼容 IE5、IE6 xhr = new ActiveXObject('Microsoft.XMLHTTP') } // 异步方式必须采用 onreadystatechange 来监听 xhr.onreadystatechange = function () { if (xhr.readyState === 4 && xhr.status === 200) { alert('The request was successful! ' + xhr.responseText) // handle statements... } } // 设置超时处理 xhr.ontimeout = function () { alert('The request was timed out') } xhr.timeout = 3000 xhr.open('POST', './test.ajax', true) // 如需设置 HTTP 请求头,必须在 open() 之后、send() 之前调用,例如: // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencode'); // 序列化 xhr.send(JSON.stringify({ name: 'test' })) } httpRequest()
下一篇:HTTP Content-Type详解
参考文章
过程中遇到的一些问题
The end.
背景
在 1999 年,微软发布 IE5,第一次引入了新功能:允许 JavaScript 脚本向服务器发起 HTTP 请求。这功能在当时并没有被引起注意,直到 2004 年 Gmail 和 2005 年 Google Map 的发布,才引起广泛的重视。在 2005 年 2 月,Ajax (
Asynchronous JavaScript And XML
,中文翻译是:异步的 JavaScript 和 XML
)这词第一次提出,指围绕这个功能进行开发的一整套做法。此后,Ajax 成为脚本发起 HTTP 通信的代名词,W3C 也在 2006 年发布了它的国际标准。什么是 XHR 对象
XHR 是
XMLHttpRequest
的简称。这是微软首先引入的一个特性,其他浏览器提供商后来都提供了相同的实现。XHR 为向服务器发送请求和解析服务器响应提供了流畅的接口,能够以异步方式从服务器取得更多信息,意味着用户单击后,可以不必刷新页面也能取得新数据。一、创建 XHR
IE5是第一款引入 XHR 对象的浏览器, 在 IE5中, XHR 对象是通过 MSXML 库中的一个 ActiveX 对象实现的,而 IE7+ 及其他标准浏览器都支持原生的 XHR 对象。
二、发送请求
发送请求的过程,包括 open 和 send 两个方法。
open
在使用 XHR 对象时,要调用的第一个方法是
open()
,该方法接收 3 个参数;GET
、POST
。还可以是HEAD
、OPTIONS
、PUT
。而由于安全风险的原因,CONNECT
、TRACE
、TRACK
被禁止使用。( 关于HTTP协议8种常用方法的详细介绍,可以点击这里)true
表示异步,false
表示同步)。如果不填写,默认true
,表示异步发送。open()
方法。send
send()
方法接收一个参数,即要作为请求主体发送的数据。调用 send() 方法后,请求被分派到服务器。GET
请求,send()
方法无参数,或者参数为null
;POST
请求,send()
方法参数为要发送的数据,字符串类型,所以一般需要序列化。三、接收响应
一个完整的 HTTP 响应由状态码、响应头集合、响应主体组成。在收到响应后,这些都可以通过 XHR 对象的属性和方法使用,主要有以下 4 个属性:
text/xml
或application/xml
,这个属性中将保存这响应数据的 XML DOM 文档(document 形式)在接收到响应之后,第一步是检测 status 属性,以确定响应已经成功返回。一般来说,可以将 HTTP状态码为 200 作为成功的标志。此时,responseText 属性的内容已经就绪,而且在内容类型正确的情况下, responseXML 也可以访问了。此外,状态码为 304 表示请求的资源并没有被修改,可以直接使用浏览器中的缓存版本。当然,也意味着响应是有效的。
无论内容类型是什么,响应主体的内容都会保存到 responseText 属性中,而对于非 XML 数据而已,responseXML 属性的值将为 null。
四、readyState
当发送一个请求后,客户端需要确定这个请求什么时候会完成,因此,XHR 对象提供了 onreadystatechange 事件机制来捕获请求的状态,继而实现响应。
每当 readyState 改变时,就会触发 onreadystatechange 事件。readyState 属性存有 XHR 的状态信息。 readyState 存有 XHR 的状态,从 0 到 4 发生变化。
open()
方法)五、超时
XHR 对象的 timeout 属性等于一个整数,单位毫秒(ms),表示该请求的最大请求时间。即在多少毫秒后,如果请求仍然没有得到结果,就会自动终止。该属性默认为 0,表示没有时间限制。
如果请求超时,将会触发 ontimeout 事件。
六、最后
只要弄清楚了整个过程,就会发现其实它并没有那么神秘,对吧。 概而括之,整个 XHR 对象的生命周期应该包括如下阶段:创建 → 初始化请求 → 发送请求 → 接收数据 → 解析数据 → 完成。
下一篇:HTTP Content-Type详解
参考文章
过程中遇到的一些问题
The end.