AJAX是一种异步的客户端和服务端进行交换数据的方法,表现是不重新加载页面的情况下,后台与服务器进行了数据交互,再部分的更新页面。
在ES6之前,主要使用浏览器提供的接口XmlHttpRequest
对象来向服务器发异步请求,从服务器获得数据。我们熟悉的Jquery的ajax方法就是对XmlHttpRequest的一种封装,它通过回调函数来传递异步操作的消息。甚至有些人认为Jquery的ajax就代表着AJAX异步通信。
从ES6推出开始,异步通信变的有些不同,首先在ES6中提供了一个原生对象Promise,通过Promise对象可以来传递异步操作的消息,在多层回调嵌套时,Promise对象是更好的解决方案。
ES6中更提供了一种新的HTTP数据请求的方式fetch,它是一个全局方法,fetch不基于XMLHttpRequest,而是XMLHttpRequest的一种替代方案。它属于原生js。
本文要说的Axios同样是XMLHTTPRequest对象的一种封装,是一个基于 promise 的 HTTP 库。
下面将用一个简单的例子来演示一下这几个方法,我在fastmock中,定义了一个接口,用于返回产品列表
关于前端开发数据mock,可以查一下资料,easy mock是个很不错的工具,但访问量太大容易挂掉
let url=`https://www.fastmock.site/mock/d6b39fde63cbe98a4f2fb92ff5b25a6d/api/products`
//原生XmlHttpRequest方法
let xhr=new XMLHttpRequest();
xhr.open("GET",url,true);
xhr.send();
xhr.onload=()=>{
if(xhr.status == 200){
console.log(JSON.parse(xhr.response)) //需要JSON.parse()方法转换为js对象
}
}
//jquery提供的ajax方法,需要进入jquery库
$.ajax({
type: "GET",
url: url,
success: (res)=>{
console.log(res)
}
});
//axios方法,需要进入axios库
axios({
url:url,
}).then((res)=>{
console.log(res);
});
//fetch
fetch(url)
.then(function(res) {
return res.json();
})
.then(function(myJson) {
console.log(myJson)
});
Axios和jquery的ajax很像,但它是基于Promise的,相比于Ajax的回调函数能够更好的管理异步操作。
AJAX和XHR实现浏览器与服务器的异步通信
ES6-Promise对象获取异步操作的消息
安装Axios
和之前的Vue.js、Vuex.js一样,我们使用script标签引入Axios
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
引入后,你会发现window对象增加了一个属性axios,它是一个函数
,下图中能看到axios的静态属性和方法。
一个Axios发送请求结束响应的过程
一、发送请求
axios(config)
参数:config是一个对象,保存着HTTP请求的配置选项,其中只有url是必选项
。
返回值:是一个promise对象,axios中习惯用then和catch方法处理异步成功和失败。
异步一旦返回结果,是被then处理还是catch处理是可以人为设定的,在axios的配置项validateStatus
返回true,promise 将被 Resolved; 否则,promise 将被 Rejected。
validateStatus配置项默认在HTTP 响应状态码大于等于200小于300时,返回true,promise 将被 Resolved。
二、接受响应
axios('https://www.fastmock.site/mock/d6b39fde63cbe98a4f2fb92ff5b25a6d/api/products')
.then(res => {
console.log('res', res);
})
.catch(err => {
console.log('err', err)
});
Axios发送的某个请求,请求成功时then方法接受的响应包含以下信息
{
data: {}, //服务器提供的响应数据
status: 200, //服务器响应的 HTTP 状态码
statusText: 'OK', //服务器响应的 HTTP 状态信息
headers: {}, //服务器的响应头
config: {}, //为请求提供的配置信息,未设置的话Axios使用默认值
request: {} //生成此响应的请求,是一个XMLHttpRequest对象
}
如本例中,返回的是:
请求失败时,catch方法接受的响应是个Error对象,本例中修改了一下api的路径,访问一个不存在的接口,得到的error对象见下:
Error对象的response属性有可能是未定义的,这种情况下一般通过响应拦截器来给response定义一个对象。
三、拦截请求和响应
用axios的interceptors实现拦截请求,拦截分为请求拦截和响应拦截,用于在发出请求前对请求进行统一的处理,接到响应后对响应的数据进行统一的处理
如:在请求时设置拦截为所有的请求头加上token,请求成功时(指HTTP请求成功)根据服务器返回的数据做相应处理,请求失败时返回错误提示。
//请求拦截器,根据项目需求在请求前进行拦截处理并返回req
axios.interceptors.request.use(req => {
req.headers['Authorization'] = '123456'; //一般token会被保存到客户端
return req;
})
// 响应拦截器
axios.interceptors.response.use(
//请求成功
res => {
if (res.status === 200) {
// 这里是和后台约定的状态码
if (res.data.code == '0000') {
return Promise.resolve(res.data)
} else {
return Promise.reject(res)
}
} else {
return Promise.reject(res)
}
},
// 请求失败
error => {
const {response} = error;
if (response) {
return Promise.reject(response);
} else {
// 处理断网的情况
return Promise.reject({
status: -1,
message: '网络已断开'
});
}
});
axios('https://www1.fastmock.site/mock/d6b39fde63cbe98a4f2fb92ff5b25a6d/api/products')
.then(res => {
console.log('返回的数据', res.data);
})
.catch(err => {
console.log('错误信息', err.message)
});
Axios用法详情
HTTP请求的配置选项
配置项 | 默认值 | 说明 |
---|---|---|
url | 用于请求的服务器URL,必选 | |
method | get | 是发出请求时使用的请求方法 |
baseURL | 将被添加到url 前面,除非url 是绝对的。 | |
transformRequest | 允许在请求数据发送到服务器之前对其进行更改,只适用于请求方法’PUT’,’POST’和’PATCH’ | |
transformResponse | 允许在 then / catch之前对响应数据进行更改 | |
headers | 是要发送的自定义 headers | |
params | 是要与请求一起发送的URL参数,必须是纯对象或URLSearchParams对象 | |
paramsSerializer | 是一个可选的函数,负责序列化params | |
data | 是要作为请求主体发送的数据,适用于请求方法“PUT”,“POST”和“PATCH” | |
timeout | 指定请求超时之前的毫秒数。 | |
withCredentials | 指示是否跨站点访问控制请求 | |
adapter | 允许自定义处理请求,这使得测试更容易。 | |
auth | 表示应该使用 HTTP 基本认证,并提供凭据。 | |
responseType | 表示服务器将响应的数据类型,包括 ‘arraybuffer’, ‘blob’, ‘document’, ‘json’, ‘text’, ‘stream’ | |
xsrfCookieName | 是要用作 xsrf 令牌的值的cookie的名称 | |
xsrfHeaderName | 是携带xsrf令牌值的http头的名称 | |
onUploadProgress | 允许处理上传的进度事件 | |
onDownloadProgres` | 允许处理下载的进度事件 | |
maxContentLength | 定义允许的http响应内容的最大大小 | |
validateStatus | 定义是否解析或拒绝给定的promise | |
maxRedirects | 定义在node.js中要遵循的重定向的最大数量。 | |
httpAgent和`httpsAgent | 用于定义在node.js中分别执行http和https请求时使用的自定义代理。 | |
proxy | 定义代理服务器的主机名和端口 | |
cancelToken | 指定可用于取消请求的取消令牌 |
请求方法别名
为了方便我们为所有支持的请求方法均提供了别名。
- axios.request(config)
发送一个HTTP请求,默认是GET请求 - axios.get(url[, config])
发送一个GET请求来获取服务器上的资源,在 URL 中附带查询参数,查询参数在config对象params配置项中设置。 - axios.delete(url[, config])
发送一个DELETE请求,删除某一个资源,默认情况下DELETE方法在 URL 中附带查询参数. - axios.head(url[, config])
发送一个HEAD请求,类似于 GET 请求,只不过返回的响应中没有具体的内容,用于获取报头 - axios.options(url[, config])
发送一个OPTIONS请求,用于查看服务器的性能。 - axios.post(url[, data[, config]])
发送一个POST请求用于向服务器提交数据,请求的参数要在http请求的消息主体中发送,一般用于新增一条数据。 - axios.put(url[, data[, config]])
发送一个PUT请求用于向服务器提交整体更新数据,请求的参数要在http请求的消息主体中发送。 - axios.patch(url[, data[, config]])
发送一个PATCH请求用于向服务器提交局部更新数据,请求的参数要在http请求的消息主体中发送。
同时发生多个请求
处理同时发生多个请求的辅助函数
- axios.all(iterable)
- axios.spread(callback)
axios.all()中的请求全部成功后,才执行axios.spread()中的函数,axios.spread()的参数是回调函数,而回调函数的参数是all方法中请求的响应,请求的响应与请求的顺序一致。
let config = {
baseURL: 'https://www.fastmock.site/mock/d6b39fde63cbe98a4f2fb92ff5b25a6d/api',
};
let urlA = `/A`;
let urlB = `/B`;
axios.all([axios.get(urlA, config), axios.get(urlB, config)]).then(
axios.spread((a, b) => {
console.log(`${a.data.girlName} looks ${b.data.looks} `);
}
)
);
配置默认值
//配置全局的 axios 默认值
axios.defaults.baseURL = 'https://www.fastmock.site/mock/d6b39fde63cbe98a4f2fb92ff5b25a6d/api';
创建一个实例
在项目中,通常会根据指定配置创建一个新的 axios实例
- axios.create([config])
let service=axios.create({
baseURL: 'https://www.fastmock.site/mock/d6b39fde63cbe98a4f2fb92ff5b25a6d/api',
timeout: 500,
});
service.get('/A').then(res=>{
console.log('res',res);
});