AJAX
1.什么是AJAX?
AJAX是浏览器提供的一套 API,可以通过 JavaScript 调用,实现局部/异步请求.
2.为什么要引入AJAX?
在没有AJAX之前,获取服务端数据需要网页刷新跳转,有了AJAX不需要网页跳转就可以发送请求.
需要网页刷新跳转的如:
1. link标签的href属性
2. script标签的src属性
3. img标签的src属性
4. a标签的href发送请求
5. 表单提交发送请求(Submit按钮)
6. iframe的src属性发送请求
3.原生AJAX
原生AJAX五部曲 | 代码 |
---|---|
1.创建请求对象 | var xhr = new XMLHttpRequest(); |
2.设置请求行(open方法) | xhr.open(请求方式,请求路径,是否异步) |
3.设置请求头(get请求不需要,post才需要) | xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded'); |
4.发送请求&设置请求体(get通过url提交数据不需要,post才需要请求体) | xhr.send(),格式:key=value,多个值用&连接 |
5.监听响应完成 | xhr.onload(IE8不支持); xhr.onreadystatechange(所有浏览器都支持) |
示例代码:
//用ajax发一个局部请求步骤
//1.创建请求对象
//本质上 XMLHttpRequest 就是 JavaScript 在 Web 平台中发送 HTTP 请求的手段,所以我们发送出去的请求任然是 HTTP 请求,同样符合 HTTP 约定的格式
var xhr = new XMLHttpRequest();
//2.调用open方法设置请求行
//参数1:请求方式
//参数2:请求路径
//相当于是设置请求行
xhr.open('get','http://wthrcdn.etouch.cn/weather_mini?city=深圳');
//3.设置请求头,(post请求才需要,get请求不需要)
//xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded');
//4.发送请求&设置请求体(post才需要,get通过url提交数据不需要)
xhr.send();
//5.监听响应完成事件(当响应完成会调用这个事件)
xhr.onreadystatechange = function(){
// 为什么要写这个判断条件?
// #这个事件会调用3次,只有当请求状态为4才代表响应完成(这时才会有响应体),也就是xhr.readyState==4
// ##上面只能保证响应完成,不能保证拿到正确的响应体,还要服务器正常响应,所以加一个 xhr.status == 200
if(xhr.readyState == 4 && xhr.status == 200){
//在判断里面处理响应体(所有代码都写在这里面)
console.log(xhr.responseText);
}
}
4.jQuery中的AJAX
属性设置/请求方法 | $.ajax | $.get | $.post |
---|---|---|---|
1.type:请求方式 | 需要设置 | 不用设置 | 不用设置 |
2.url:请求路径 | |||
3.data:提交的数据 | 字符串或对象 | 在jQuery1.12以前,是不支持传入对象,需要一个一个写参数 | 同$.get |
4.dataType:表明响应体类型 | |||
5.success:响应成功的回调函数 | |||
6.error:响应失败的回调函数 |
$.ajax示例代码:
//jQuery在线CDN引用地址
<script src="https://cdn.bootcss.com/jquery/3.1.1/jquery.min.js"></script>
<script>
$.ajax({
// 请求方式
type: "get",
// 请求路径
url: "http://wthrcdn.etouch.cn/weather_mini?city=深圳",
// 请求提交的数据,get不需要
// 传递的数据可以是字符串也可以是对象,传对象,它会自动把对象转换成字符串的形式
// 1.data:"name=jack&age=16"
// 2.data: { name: "jack", age: 16 }
// 告诉jQuery,响应体是json类型的数据,帮我们自动转成对象,在控制台可以看到打印的是对象
dataType: "json",
// 响应成功的回调函数,obj就是响应体
success: function (obj) {
console.log('success');
console.log(obj);
},
// 当发生错误,有可能是请求失败,也有可能是其他错误,会进到这个函数里
error: function (res) {
console.log('error');
console.log(res);
}
});
</script>
5.进阶:基于Promise封装Ajax
(1)Promise 对象:ECMAscript 6 新增,主要用于解决异步回调的问题.
1.简单说是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果.
2.从语法上说,promise是一个对象,从它可以获取异步操作的消息.
(2)Promise对象的特点
1.promise对象代表一个异步操作,有三种状态,pending(进行中)、fulfilled(已成功)、rejected(已失败).
2.状态改变只有两种:从pending变为fulfilled,从pending变为rejected.
3.只有异步操作的结果,可以决定当前是哪一种状态,任何其他操作都无法改变这个状态,这也是promise:“承若”这个名字的由来.
4.一旦状态改变就不会再变,任何时候都可以得到这个结果,这与事件(event)完全不同,事件的特点是:如果你错过了它,再去监听是得不到结果的.
(3)Promise对象的创建:
//1.使用 new 调用 Promise 构造函数进行实例化.
//2.Promise 构造函数包含一个参数和一个带有 resolve(解析)和 reject(拒绝)两个参数的回调.
var promise = new Promise(function(resolve, reject) {
// 异步处理
// 当异步代码执行成功时,我们会调用resolve(...), 当异步代码失败时就会调用reject(...)
});
(4)Promise封装Ajax:
let hxios = {
get(url) {
// 返回新建的promise对象
return new Promise((resolve, reject) => {
// 1.设置请求对象
let xhr = new XMLHttpRequest();
// 2.设置请求行
xhr.open('GET', url);
// 3.设置请求头(get请求不需要)
// xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 4.发送请求&设置请求体
xhr.send();
// 5.监听响应完成
// 成功回调函数
xhr.onload = function () {
// promise resolve
resolve(xhr.responseText);
}
// 错误回调函数
xhr.onerror = function () {
// 调用reject
reject('请求出错啦')
}
})
},
post(url) {
// 返回新建的promise对象
return new Promise((resolve, reject) => {
// 1.设置请求对象
let xhr = new XMLHttpRequest();
// 2.设置请求行
xhr.open('POST', url);
// 3.设置请求头
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
// 4.发送请求&设置请求体
xhr.send();
// 5.监听响应完成
// 成功回调函数
xhr.onload = function () {
// promise resolve
resolve(xhr.responseText);
}
// 错误回调函数
xhr.onerror = function () {
// 调用reject
reject('请求出错啦')
}
})
},
}
Promise构造函数 | promise实例对象 |
---|---|
原型对象Promise.prototype上有then和catch方法 | promise实例都可以调用then和catch方法 |
调用上述Promise封装的AJAX进行天气查询:
//promise.then(onCompleted, onRejected);方法实现链式调用.
//1.onCompleted:必需,成功时执行的回调函数.
//2.onRejected:可选,失败时执行的回调函数.
//3.promise.catch方法可以当作.then(null, rejection)的别名,失败时执行的回调函数.
//4.不管是then方法还是catch方法返回的都是一个新的Promise实例,这意味着Promise可以链式调用then和catch,每一个方法的返回值作为调用下一个方法的实例对象.
hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=深圳')
.then(res => {
console.log(res);
// 查完了深圳查北京,返回promise对象
return hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=北京')
}).then(res => {
console.log(res);
// 查完了北京查武汉,再次返回promise对象
return hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=武汉')
}).then(res => {
console.log(res);
})
6.进阶:async/await协同promise发AJAX请求
(1)async/await:ES7(ES2017)中提出的前端异步特性:
async | 关键词await(只能在async函数中使用) |
---|---|
用于声明一个函数是异步的 | await可以让JS进行等待,直到这个异步执行得到结果后(返回的不是promise对象,await也会强制转换),JS才会继续往下执行 |
注意:有async的内层可以没有await,有await的外层一定要有async声明这是异步函数
调用上述Promise封装的AJAX+async/await进行天气查询:
// 用async 修饰的函数 内部的代码执行 是从上往下
async function searchWeather() {
// 希望按照顺序执行的代码 全都丢到 async修饰的函数中
// await 把 后面 Promise 中then的 回调函数的参数 返回给你
let res1 = await hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=深圳')
console.log(res1);
let res2 = await hxios.get('http://wthrcdn.etouch.cn/weather_mini?city=广州')
console.log(res2);
}
searchWeather();
本文同步发表在我的个人博客:https://www.lubaojun.com/