在刚开始学 JavaScript
时,最深恶痛绝的三个 JS怪👹:this妖、原型精和 AJAX魔
最近在写总结回顾时竟意外发现这三大怪早已在不知不觉中被我消化吸收了,趁着热乎记下来✍~~~
有请今天的出场嘉宾🎤:AJAX魔
什么是 AJAX
AJAX 是一种用于创建快速动态网页的技术,它使用 XMLHttpRequest
对象与服务器通信。 它可以使用JSON,XML,HTML和text文本等格式发送和接收数据。AJAX最吸引人的就是它的“异步”特性,它可以在不重新刷新页面的情况下与服务器通信,交换数据,或更新页面。
什么是异步
不等任务执行完,直接执行下一个任务
举个例子 🌰
周末我和闺蜜去逛gai,我们打算去吃海底捞,排队的人很多,于是我们手机扫码排号,然后继续逛gai,过一会收到叫号通知就可以进去吃火锅啦~
「排号」这件事并没有立即得到结果(进去吃火锅),所以这是一个异步任务
AJAX 请求数据流程与此类似。
浏览器通过 XMLHttpRequest
对象向服务器发出HTTP请求与接收HTTP响应,浏览器接着做其他事情,等收到 XMLHttpRequest
对象返回来的数据再渲染页面。
AJAX 的使用
1. 创建Ajax核心对象XMLHttpRequest
var httpRequest = null;
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
httpRequest = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE 6 and older
httpRequest = new ActiveXObject("Microsoft.XMLHTTP")
}
2. 发送HTTP请求
httpRequest.open(method, url, async)
httpRequest.send()
method:HTTP请求方法 - 有GET,POST,HEAD以及服务器支持的其他方法
url:文件在服务器上的位置。由于安全原因,默认不能调用第三方URL域名
async:用于设置请求true(异步)或 false(同步)
send() 方法的参数可以是任何你想发送给服务器的内容。
如果是 POST 请求的话,需注意:
- 在调用 send() 方法获取表单数据前要设置请求头的格式内容
httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
- 发送表单数据时应该用服务器可以解析的格式,像查询语句,JSON,XML等
// 举例
httpRequest.send("name=xcl&anothername=April")
3. 处理服务器响应
有关的 API :
XMLHttpRequest.onreadystatechange:只要 readyState 属性发生变化,就会调用相应的处理函数
XMLHttpRequest.response:返回响应的正文,返回的类型取决于 responseType 属性
XMLHttpRequest.responseText:服务器以文本字符的形式返回
XMLHttpRequest.responseXML:以 XMLDocument 对象方式返回,之后就可以使用JavaScript来处理
XMLHttpRequest.readyState:返回一个 XMLHttpRequest 代理当前所处的状态(请求的状态码),它的值含义:
0 未初始化 – 尚未调用.open()方法
1 启动 – 已经调用.open()方法,但尚未调用.send()方法
2 发送 – 已经调用.send()方法,但尚未接收到响应
3 接收 – 已经接收到部分响应数据
4 完成 – 已经接收到全部响应数据,而且已经可以在客户端使用了
XMLHttpRequest.status:返回了 XMLHttpRequest 响应中的数字状态(请求的响应状态码),它的值含义:
1** 信息 – 服务器收到请求,需要请求者继续执行操作
2** 成功 – 操作被成功接收并处理
3** 重定向 – 需要进一步的操作以完成请求
4** 客户端错误 – 请求包含语法错误或无法完成请求
5** 服务器错误 – 服务器在处理请求的过程中发生了错误
一般通过检查响应码 200 OK 判断 AJAX 有没有成功
一般我们会使用异步 AJAX(即 open() 的第三个参数未特别指定或设为 true),在发送请求时,提供一个回调函数负责处理响应,代码大概长这样:
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === 4 && httpRequest.status === 200) {
/* 对 httpRequest.response 的一些操作 */
}
}
如果是使用同步 AJAX(即 open() 的第三个参数设为 false),则直接在 send() 方法之后执行要进行的操作即可。但不建议这样做,它的用户体验很糟糕,可能会使页面在请求期间卡住
AJAX 的用法大概就是如此,把所有代码整合到一块是这样的:
var httpRequest = null;
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
httpRequest = new XMLHttpRequest()
} else if (window.ActiveXObject) { // IE 6 and older
httpRequest = new ActiveXObject("Microsoft.XMLHTTP")
}
httpRequest.open(method, url, async)
httpRequest.send()
httpRequest.onreadystatechange = function () {
if (httpRequest.readyState === 4 && httpRequest.status === 200) {
/* 对 httpRequest.response 的一些操作 */
}
}
手动封装 AJAX
这里会用到 Promise
对象【MDN传送门】
ajax = (method, url, options) => {
return new Promise((resolve, reject) => {
const {success, fail} = options
const request = new XMLHttpRequest()
request.open(method, url)
request.onreadystatechange = () => {
if(request.readyState === 4){
if(request.status < 400){
resolve.call(null, request.response)
}else if(request.status >= 400){
reject.call(null, request)
}
}
}
request.send()
})
}
这个封装只是为了熟悉 Promise
的用法,尚还存在许多问题(post 无法上传数据、不能设置请求头等)
jQuery.ajax
用法:
jQuery.ajax()
jQuery.ajax( url [, settings ] )
jQuery.ajax( [settings ] )
返回 jqXHR 对象,常用 API:
jqXHR.done(function(data, textStatus, jqXHR) {}):一个可供选择的 success 回调选项的构造函数
jqXHR.fail(function(jqXHR, textStatus, errorThrown) {}):一种可供选择的 error 回调选项的构造函数
jqXHR.always(function(data|jqXHR, textStatus, jqXHR|errorThrown) { }):一种可供选择的 complete 回调选项的构造函数
jqXHR.then(function(data, textStatus, jqXHR) {}, function(jqXHR, textStatus, errorThrown) {}):包含了 .done() 和 .fail()方法的功能
axios
参考文章: