1.什么是AJAX?
AJAX是“Asynchronous JavaScript And XML”的缩写(即:异步的JavaScript和XML),是一种实现无页面刷新获取服务器数据的混合技术。
1.1 XML是什么?
XML是“Extensible Markup Language”的缩写(即:可拓展标记语言),是一种特征类似HTML,用来描述数据是什么,并承载数据的标记语言;而JSON仅仅是一种数据格式。需要注意的是,JSON并不是XML的替代品,两者各自有其适应的场景。
1.2 AJAX做到了什么?
页面数据变动时,只向服务器请求新的数据,并且在阻止页面刷新的情况下,动态的替换页面中展示的数据;通过阻止浏览器接受响应时刷新页面提升了互联网用户的使用体验,还使开发者重新思考互联网应用的构建。
AJAX技术并不只是操作XMLHttpRequest对象发起异步请求,而是为了实现“无页面刷新的资源获取”的一些列技术的统称,这些技术包括了:
JavaScript:用来在获取数据后,通过操作DOM或其他方式达成目标;
客户端(即浏览器)提供的实现异步服务器通信的XMLHttpRequest对象;
服务器端允许浏览器向其发起AJAX请求的相关设置;
2.AJAX请求
XMLHttpRequest对象是浏览器提供的一个API,用来顺畅地向服务器发送请求并解析服务器响应。XMLHttpRequest只是一个JavaScript对象,确切的说,是一个构造函数(不是JavaScript原生的),而是浏览器提供的。
2.1 GET请求和POST请求
GET请求用于获取数据。
POST请求用于向服务器发送应该被保存的数据,因此POST请求天然比GET请求多需要一份需要被保存的数据。
2.2 同步请求和异步请求
同步意味着一旦请求发出,任何后续的JavaScript代码不会再执行。
异步则是当请求发出后,后续的JavaScript代码会继续执行,当请求成功后,会调用相应的回调函数。
2.3 AJAX技术流程
JavaScript:用来在获取数据后,通过操作DOM或其他方式达成目标;
客户端(即浏览器)提供的实现异步服务器通信的XMLHttpRequest对象;
服务器端允许浏览器向其发起AJAX请求的相关设置;
3. XMLHttpRequest对象
AJAX技术的核心仍是XMLHttpRequest对象,但不仅是XMLHttpRequest对象那么简单。XMLHttpRequest对象是浏览器提供的一个API,用来向服务器发送请求并解析服务器响应,整个过程中浏览器页面不会被刷新。
XMLHttpRequest只是一个JavaScript对象,是一个构造函数。它是由客户端(即浏览器)提供的(而不是JavaScript原生的),除此之外,它有属性,有方法,需要通过new关键字进行实例化。
首先,我们来创建一个XML对象的实例:
const xhr = new XMLHttpRequest()
该实例的属性和方法有:
方法
- .open():准备启动一个AJAX请求;
- .setRequestHeader():设置请求头部信息;
- .send():发送AJAX请求;
- .getResponseHeader(): 获得响应头部信息;
- .getAllResponseHeader():获得一个包含所有头部信息的长字符串;
- .abort():取消异步请求;
属性
- .responseText:包含响应主体返回文本;
- .responseXML:如果响应的内容类型时text/xml或application/xml,该属性将保存包含着相应数据的XML DOM文档;
- .status:响应的HTTP状态;
- .statusText:HTTP状态的说明;
- .readyState:表示“请求”/“响应”过程的当前活动阶段
.open()方法接收三个参数:请求方式,请求URL地址和是否为异步请求的布尔值。
.open()方法参数举例:
// 启动一个“demo.php”的GET同步请求。
xhr.open("get", "demo.php", false)
而需要发送的数据会作为.send()方法的参数最终被发往服务器,该数据可以是任意大小,任意类型。
4. 发送请求与处理响应
XMLHttpRequest对象提供的.setRequestHeader()方法为我们提供了一个操作这两种头部信息的方法,并允许自定义请求头的头部信息。
所以在发送请求之前我们根据安全性最好自定义请求头,之后利用.open()方法确定了请求方式,等待响应的方式和请求地址,还通过.setRequestHeader()自定义了响应头,之后就可以发送请求,最终处理相应。
const xhr = new XMLHttpRequest()
xhr.open("get", "demo.php", false)
xhr.setRequestHeader("tripleH", "K9999")
xhr.send(null)
// 当为同步的AJAX请求,只有当服务器响应后才会继续执行下面的代码
// 所以xhr.status的值一定不为默认值
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {
alert(xhr.responseText)
} else {
alert("Request was unsuccessful: " + xhr.status)
}
但是,当我们的请求为异步时,由于是异步的请求,在xhr.send(null)语句被执行后,JS引擎会紧接着执行下面的判断语句,而这时由于尚未来得及响应,我们注定会得到一个默认的xhr.status值,因此,不可能获取请求的资源。这时,我们需要通过为XMLHTTPRequest实例添加onreadystatechange事件处理程序来处理。
xhr实例的readystatechange事件会监听xhr.readyState属性的变化,你可以将这个属性想象为一个计数器,随着AJAX流程的推进而不断累加,其可取的值如下:
0:未初始化 – 尚未调用.open()方法;
1:启动 – 已经调用.open()方法,但尚未调用.send()方法;
2:发送 – 已经调用.send()方法,但尚未接收到响应;
3:接收 – 已经接收到部分响应数据;
4:完成 – 已经接收到全部响应数据,而且已经可以在客户端使用了;
JSONP原理与方案
JSONP本质:动态创建script标签,然后通过它的src属性发送跨域请求,之后服务器端响应的数据格式为【函数调用】,所以在发送请求之前必须先声明一个函数,并且函数的名字与参数中传递的名字一致。这里声明的函数是由服务器响应的内容(实际就是一段JS代码-->函数调用)来调用。
web客户端通过与调用脚本一模一样的方式,来调用跨域服务器上动态生成的js格式文件(一般以JSON为后缀),显而易见,服务器之所以要动态生成JSON文件,目的就在于把客户端需要的数据装入进去。
AJAX和JSONP其实本质上是不同的东西。AJAX的核心是通过XmlHttpRequest获取非本页内容,而JSONP的核心则是动态添加的结果。