一、axios概念
axios:基于Promise封装的ajax库(核心还是ajax的四步操作)
- ajax请求一般采用异步
- ajax的串行:第一个接口请求成功,才能继续请求第二个...
- ajax的并行:同时发送多个接口请求,当所有接口都请求成功,再去执行某些事情 => Promise.all
- 基于Promise管理ajax的异步操作 Fetch:浏览器新增的API,默认就是基于Promise管理的(核心不是XMLHttpRequest)
//传统方案会引发回调地狱
$.ajax({
url: 'http://127.0.0.1/api1',
success: result => {
$.ajax({
url: 'http://127.0.0.1/api2',
success: result => {
...
}
})
}
})
//返回的是promise实例
axios.get('http://127.0.0.1/api1').then(response => {
return axios.get('http://127.0.0.1/api2');
}).then(response => {
...
})
二、axios学习目录
-
axios的的基础使用
-
axios的二次封装
- 拦截器
- 一些常规配置
1、axios的基础使用
//返回的都是Promise实例
axios([config])
axios([url], [config])
axios.get/head/delete/options([url], [config])
axios.post/put([url], [data], [config])
//axios.get使用
let baseUrl = 'http://127.0.0.1';
axios.get('/api1', {
baseUrl, //请求地址的公共部分:最后请求的地址 baseUrl + url
headers: {
'Content-Type': 'application-www-form-urlencoded'
}, //自定义请求头信息
timeout: 0, //在CORS跨域请求中,是否允许携带资源凭证
responseType: 'json', //预设服务器返回的数据内容:服务器该返回啥还是啥(后台决定返回格式),
//而预设的意思是:把服务器返回的结果,处理成想要的数据格式,支持设定的格式有:'arraybuffer', 'blob','document','json','text','stream')
validateStatus: function(status){
return status >= 200 && status <= 300;
}, //它规定了请求结果中,哪些状态码代表请求成功,哪些代表失败,从而决定执行then还是catch
params: {
name: 'luban',
age: 4
}//get请求传递参数,最后都会拼接到url的末尾(必须是一个无格式对象或URLSearchParams对象)
}).then(response => {
//从服务器成功获取对象
//status / statusText:状态码的描述
//request:原生的xhr对象
//headers:存储部分响应头信息
//config:我们发送请求的配置项
//data:服务器响应主体的信息(我们获取的数据)
return response.data;
}).catch(reason => {
//从服务器获取失败数据
//返回的是ERROR类的实例
//message:错误的信息
//request:原生的xhr对象
//config:我们发送请求的配置项
//response:等同于成功的response,但是可能没有,如果向服务器发请求,服务器接收 ,但是返回非2开头的状态码(虽然失败,但是最起码告诉我们具体的结果了),这种是有response。如果请求没有到达服务器(如断网了),则没有response
console.log('失败');
return Promise.reject(reason.message);
}).then(result => {
//result = response.data
console.log('响应主体信息', result);
})
axios.post('/user/update', {
userId: 1,
desc: '鲁班真可爱'
}, {
baseUrl,
//post是基于请求主体传递给服务器信息
/*
传递的数据格式:form-data / x-www-from-urlencoded / raw / binary / GraphQL
form-data:一般用于表单提交或者文件流(文件上传)Content-type: multipart/form-data
x-www-from-urlencoded: xxx=xxx&xxx=xxx application/x-www-from-urlencoded
raw: 文本格式 "普通文本 text/plain" "json字符串 application/json"
binary: 进制编码格式 application/octet-stream
*/
headers: {
"Content-type": "application/x-www-from-urlencoded"
},
//transformRequest:把请求主体传递的信息 在发送给服务器之前,变成我们想要的格式
transformRequest: data => {
//data就是我们配置的对象
return Qs.stringify(data);
}
})
2、axios的二次封装
/*
- axios库中的默认配置
- 提取的公共参数配置 axios.defaults
- 发送请求时单独写的配置,axios.get([url], [config])
优先级自下而上
*/
//需求1:真实项目中,我们可能基于环境变量(开始/测试/生产)控制地址前缀不一样
let env = process.env.NODE_ENV; //获取webpack/package.json中配置的环境变量
switch(env) {
case "production":
axios.defaults.baseURL = "http://xxx.x.x.x/xxxx";
break;
case "test":
axios.defaults.baseURL = "http://xxx.x.x.x/xxxx";
break;
default:
axios.defaults.baseURL = "http://xxx.x.x.x/xxxx";
}
axios.defaults.baseURL = "http://127.0.0.1/8080";
axios.defaults.timeout = 10000;
axios.defaults.withCredentials = true;
axios.defaults.headers = {
"Content-type": "application/x-www-from-urlencoded"
}
axios.defaults.transformRequest = data => Qs.stringify(data);
axios.defaults.validateStatus = status => (status >= 200 && status <= 300);
//请求拦截器:在我们把数据发送给服务器之前,拦截到我们设置的config,然后二次配置
axios.interceptors.request.use(config => {
//config: 存储现有配置项
//携带token
let token = localStorage.getItem('token');
token && (config.headers.Authorization = token);
return config;
});
//响应拦截器
axios.interceptors.response.use(response => {
//response: 成功返回的结果
return response.data;
}, reason => {
//失败返回的信息
//统一在这里针对失败的结果做不同的提示后者处理
if (reason.response) {
//服务器返回信息,只是状态码不是2开始的:根据不同状态码做提示
switch(reason.response.status) {
case 401:
//权限问题
break;
case 403:
//Token过期
break;
case 404:
//地址错误
break;
}
} else {
//需要检验是否断网
if(!navigator.onLine) {
}
}
return Promise.reject(reason.message);
});