Open phenomLi opened 6 years ago
我们在使用ajax的时候,出于方便,通常使用jquery的$.ajax()方法,简单快捷,帮助我们屏蔽了许多底层的细节。久而久之我们很容易就会遗忘掉原生ajax的一些知识点,比如XMLHttpRequest。下面我就帮助大家对ajax的工作流程梳理一下。 XMLHttpRequest是ajax实现的基础,我们常常用它来对服务器发送一个异步请求:
$.ajax()
XMLHttpRequest
//实例化一个XMLHttpRequest对象 const xhr = new XMLHttpRequest(); //onreadystatechange方法:判断当前请求的进度 xhr.onreadystatechange = function() { //当readyState的值为4时获取返回的值 if(xhr.readyState === 4) { console.log(xhr.responseText); } } //指定http方法和目标主机,建立连接 xhr.open('GET', 'localhost:8080'); //发送请求 xhr.send();
通常,一次http数据请求,要经过
建立连接 ==> 发送请求 ==> 响应请求 ==> 返回数据
4个阶段,所以说XMLHttpRequest在获取返回的数据的时候,一定要在特点的阶段获取,不然肯定是获取不了的,很显然xhr.readyState === 4的时候,是数据返回成功的阶段。那么在其他阶段,xhr.readyState的值又对应什么呢,我们可以查阅一下MSDN: 可以看到,各个readyState对应的阶段为:
xhr.readyState === 4
xhr.readyState
readyState
readyState === 0:XMLHttpRequest对象初始化(实例化)完成
readyState === 0
readyState === 1:open方法完成(连接建立),未调用send方法(未发送)
readyState === 1
open
send
readyState === 2:send方法被调用(发送请求)
readyState === 2
readyState === 3:已响应,但responseText不可用(返回的数据未准备好)
readyState === 3
responseText
readyState === 4:所有工作都已完成,responseText可用
readyState === 4
同样的,我们可以很容易想到, onreadystatechange 这个方法肯定不是只被调用一次,而是会被调用多次,在什么时候被调用呢?很明显,是在每次readyState的值发生更改的时候。
onreadystatechange
看到这里,相信大家已经对ajax的整个工作流程有一个大概的轮廓了,但是为了加深理解,我们可以按照上面的思路,造一个假的XMLHttpRequest对象,模拟一下ajax的工作流程。
首先我们要确定我们的MyXMLHttpRequest对象里面有哪些成员变量和方法:
MyXMLHttpRequest
resposeText
status:保存http状态码
status
open方法
send方法
onreadystatechange方法
setReadyState方法:用作设置readyState的值
setReadyState
然后就可以一步一步写我们的 MyXMLHttpRequest 类,由于偷懒,我这里就直接放完整代码了:
export default class MyXMLHttpRequest { public readyState: number; public responseText: string; public status: number; constructor() { //在初始化对象时设置readyState为0 this.setReadyState(0); console.log('MyXMLHttpRequest被实例化,readyState值为: ' + this.readyState); } /* * 设置readyState的方法 * @param newState<number> 新的readyState的值 * @return <void> */ setReadyState(newState: number): void { this.readyState = newState; //每次readyState发生改变都会调用onreadystatechange方法 this.onreadystatechange && this.onreadystatechange(); } /* * onreadystatechange方法 */ onreadystatechange(): void {} /* * open方法 * @param httpMethod<string> http请求方式 * @param targetHost<string> 请求的目标主机 * @return <void> */ open(httpMethod: string, targethost: string): void { //请求开启,open方法被调用,readyState设置为1 this.setReadyState(1); } /* * send方法 */ send(): void { //send方法被调用,readyState设置为2 this.setReadyState(2); //模拟响应请求 setTimeout(() => { //响应成功,readyState设置为3 this.setReadyState(3); //模拟接收返回的数据 setTimeout(() => { //http状态码为200,表示请求没有错误 this.status = 200; //responseText的数据也已经准备完成 this.responseText = 'Phenom'; //所有工作已经完成,readyState设置为4 this.setReadyState(4); }, 200); }, 100); } }
由于客观原因限制,我们没有办法用浏览器环境下的javascript来真实地进行http请求的发送和接收,所以这段代码是不能真正向服务器发送请求的,但是没关系,那不是重点, 我们主要目的是要搞清楚XMLHttpRequest在每个阶段做了什么工作。 由于XMLHttpRequest发送请求是异步的,我们可以用setTimeout来模拟异步的请求流程。
最后我们像普通的ajax操作一样,写我们的代码:
const myXhr = new MyXMLHttpRequest(); myXhr.onreadystatechange = function() { console.log('当前的readyState值为: ' + myXhr.readyState); if(myXhr.readyState === 4) { console.log('responseText的值为: ' + myXhr.responseText); } }; myXhr.open('GET', 'localhost:8080'); myXhr.send();
运行结果: perfect!
最后总结一下,XMLHttpRequst的工作流程为:
XMLHttpRequst
XMLHttpRequest对象被初始化,对应的readyState为0
open方法被调用,启用连接,对应的readyState为1
send方法被调用,发送请求,对应的readyState为2
响应完成,但responseText准备好,对应的readyState为3
responseText已完成,所有工作都已完成,对应的readyState为4
我们在使用ajax的时候,出于方便,通常使用jquery的
$.ajax()
方法,简单快捷,帮助我们屏蔽了许多底层的细节。久而久之我们很容易就会遗忘掉原生ajax的一些知识点,比如XMLHttpRequest
。下面我就帮助大家对ajax的工作流程梳理一下。XMLHttpRequest
是ajax实现的基础,我们常常用它来对服务器发送一个异步请求:通常,一次http数据请求,要经过
4个阶段,所以说
XMLHttpRequest
在获取返回的数据的时候,一定要在特点的阶段获取,不然肯定是获取不了的,很显然xhr.readyState === 4
的时候,是数据返回成功的阶段。那么在其他阶段,xhr.readyState
的值又对应什么呢,我们可以查阅一下MSDN:可以看到,各个
readyState
对应的阶段为:readyState === 0
:XMLHttpRequest
对象初始化(实例化)完成readyState === 1
:open
方法完成(连接建立),未调用send
方法(未发送)readyState === 2
:send
方法被调用(发送请求)readyState === 3
:已响应,但responseText
不可用(返回的数据未准备好)readyState === 4
:所有工作都已完成,responseText
可用同样的,我们可以很容易想到,
onreadystatechange
这个方法肯定不是只被调用一次,而是会被调用多次,在什么时候被调用呢?很明显,是在每次readyState
的值发生更改的时候。看到这里,相信大家已经对ajax的整个工作流程有一个大概的轮廓了,但是为了加深理解,我们可以按照上面的思路,造一个假的
XMLHttpRequest
对象,模拟一下ajax的工作流程。MyXMLHttpRequest
首先我们要确定我们的
MyXMLHttpRequest
对象里面有哪些成员变量和方法:readyState
resposeText
status
:保存http状态码open
方法send
方法onreadystatechange
方法setReadyState
方法:用作设置readyState
的值然后就可以一步一步写我们的
MyXMLHttpRequest
类,由于偷懒,我这里就直接放完整代码了:由于客观原因限制,我们没有办法用浏览器环境下的javascript来真实地进行http请求的发送和接收,所以这段代码是不能真正向服务器发送请求的,但是没关系,那不是重点, 我们主要目的是要搞清楚
XMLHttpRequest
在每个阶段做了什么工作。 由于XMLHttpRequest
发送请求是异步的,我们可以用setTimeout来模拟异步的请求流程。最后我们像普通的ajax操作一样,写我们的代码:
运行结果:
perfect!
总结一下
最后总结一下,
XMLHttpRequst
的工作流程为:XMLHttpRequest
对象被初始化,对应的readyState
为0open
方法被调用,启用连接,对应的readyState
为1send
方法被调用,发送请求,对应的readyState
为2响应完成,但
responseText
准备好,对应的readyState
为3responseText
已完成,所有工作都已完成,对应的readyState
为4