什么是axios
axios是一个基于promise封装的ajax网络请求库,通过promise来进行管控,可以有效的解决ajax回调地狱的问题。
axios基础语法
axios的属性和方法:
Axios: 实现promise管控ajax请求的一个类方法,axios执行的时候返回的其实就是一个Axios的实例Cancel、CancelToken: 在发送请求的工程中控制中断请求all: 通过promise.all来进行控制的,当所有的请求成功返回的实例才是成功态spread: 结合all获取请求数组中的promise实例,解析all的结果create: 创建axios的实例,多用于项目中有多个服务器共同工作时,请求不同服务器通过不同的实例对象,并且添加不同的默认配置default: 指向axios函数自己defaults: 给请求添加的默认配置项adapter: 自定义处理请求,一般不用headers: 请求头信息- 自定义请求头
common: 默认的请求头信息,默认->{Accept: "application/json, text/plain, */*"},发送时自动拼接到headers上get/delete/head:GET类请求的请求头信息,无默认,发送时自动拼接到headers上post/put/patch:POST类请求的请求头信息,默认->{"ConTent-Type":"application/x-www-form-urlencoded"},发送时自动拼接到headers上
maxBodyLength: -1 定义允许的请求内容的最大尺寸maxContentLength: -1 定义允许的响应内容的最大尺寸timeout: 0 设置超时时间transformRequest(): 在发送请求前进行一些配置处理,一般做主体信息转换transformResponse(): 转换响应主体response的内容,一般不用validateStatus(): 设置状态码校验规则,不符合规则就代表失败xsrfCookieName:"XSRF-TOKEN"防止XSRF攻击xsrfHeaderName:"X-XSRF-TOKEN"防止XSRF攻击
request: 发送请求isCancel(): 判断请求是否是中断的(断网或者自己调用Cancel中断)isAxiosError(): 判断是否时axios层面的错误iterceptors: 拦截器resquest: 请求拦截器,一般做携带token标识response: 响应拦截器,对响应做统一处理
get/delete/head/options:GET类请求快捷方式post/put/patch:POST类请求快捷方式
axios配置项axios(options)->options:
baseURl: 默认地址url: 加上baseURL形成完整的地址method: 请求方式transformRequest: 同上transformResponse: 同上headers: 同上params:get请求时的参数,POST请求下不起作用paramsSerializer(): 将get的参数序列化data: 请求主体,get下不起作用timeout: 同上withCredentials: 允许携带资源凭证responseType: 响应主体信息的类型xsrfCookieName: 同上xsrfHeaderName: 同上onUploadProgress(): 监听上传的进度,传递一个事件对象onDownloadProgress(): 监听下载的进度,也会传递一个事件对象maxContentLength: 同上maxBodyLength: 同上validateStatus(): 同上cancelToken(): 同上
axios({
baseURL: "http://127.0.0.1:8888",
url:"/user/list",
method:"get",
params:{
lx:1,
name:"小王"
},
data:{
// post系列请求才起作用
// ...请求主体信息
// 数据格式可以是以下几种:
// 1. raw(默认的时json):json,text,xml...
// 2. x-www-form-urlencoded: 'lx=xx&name=xx'的格式
// 3. form-data:文件上传或者表单
// 4. binary:进制流格式,多用于大文件上传
},
headers:{
// ...请求头
},
transformRequest(data, headers){
// ...进行数据转换
},
timeout: 0,
validateStatus(status){
// 对状态码进行处理,返回true,axios才能继续走下去
}
})
// 快捷方法
axios.get("http://127.0.0.1:8888/user/list",{
params:{
lx:1,
name:"小王"
},
headers:{
// ...请求头
},
})
axios.post("http://127.0.0.1:8888/user/list",{
// 传递的data数据,请求主体信息
},{
params:{
lx:1,
name:"小王"
},
headers:{
// ...请求头
},
})
axios响应成功的信息
config: 请求的配置信息data: 后端返回的信息(一般会进行二次封装将这个信息直接返回)headers: 响应头信息request: 发送的原生ajax信息status:http响应状态码statusText:http状态码的信息
axios响应失败的信息
resopnse: 失败的响应信息:当请求中断、超时或者断网时值为undefined- 和响应成功的信息一样,只是值不一样
config: 请求的配置项isAxiosError: 是否为axios错误request: 原生ajax实例对象toJSON(): 转换JSON方法message: 错误的信息code:'ECONNABORTED',当超时或者被中断的时候出现
axios自己取消请求CancelToken
const CancelToken = axios.CancelToken;
const source = CancelToken.source();
axios.get('/user/12345', {
cancelToken: source.token
}).catch(function(thrown) {
if (axios.isCancel(thrown)) {
console.log('Request canceled', thrown.essage);
} else {
// 处理错误
}
});
axios.post('/user/12345', {
name: 'new name'
}, {
cancelToken: source.token
})
// 取消请求(message 参数是可选的)传递给错误信息的message
source.cancel('Operation canceled by the user.');
封装axios
在项目中,有很多的接口都有统一的配置,这个时候提取出来提前配置好能缩短开发周期,更快捷的开发。
baseURlheaderstransformRequest()timeoutwithCredentialsvalidateStatus()interceptors.request()interceptors.response()
/*
axios的二次封装,将常用的公共配置项提前配置好,对响应内容做统一处理
*/
/*
baseURL: 在项目中通过环境变量来进行区分(node中的环境变量),不同环境使用不同的服务器
+ 开发 development
+ 测试 test
+ 灰度 gray(一般在上线很重要的功能是会存在一个灰度环境,其目的是慢慢的将用户转移,防止全部转移出现重大bug难以承受,如果转移的没问题在慢慢进行转移)
+ 生产 production
*/
// let env = process.env.NODE_ENV || "development";
// switch (env) {
// case "development":
// axios.defaults.baseURl = "http://127.0.0.1:8888";
// break;
// case "test":
// axios.defaults.baseURl = "http://api.test:8888";
// break;
// case "development":
// axios.defaults.baseURl = "http://api:8888";
// break;
// }
// 超时时间
axios.defaults.timeout = 1000;
// 允许携带资源凭证
axios.defaults.withCredentials = true;
// 校验http状态码
axios.defaults.validateStatus = (status) => {
return status >= 200 && status < 400;
}
/*
设置请求头
+ headers[xx]=xx 直接给设置请求头
+ headers.common[xx]=xx 存在common,会默认给每个请求加上请求头
+ headers.post/get[xx]=xx 对应请求的请求头走这里,这个会覆盖common和直接给headers写
*/
// 对于Content-Type这个特殊的请求头来说,@1这个比重比@2@3common/post/get...重,
// 仅仅比直接写配置项低一点,也就是可以将请求头强制改变为这个,
// 而其他的也设置了这样的效果,但是axios还是会根据所传递的参数去给Content-Type赋值
axios.defaults.headers["Content-Type"] = "a"; // @1
axios.defaults.headers.common["Content-Type"] = "b"; // @2
axios.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded"; // @3
// 而对于那些没有特殊性的请求头的话直接就可以设置上去
axios.defaults.headers.get["Authorization"] = "c";
axios.defaults.headers.post["Authorization"] = "a";
// 设置请求前的数据格式处理
axios.defaults.transformRequest = (data, headers) => {
if (data === null || typeof data !== "object") return data;
// 获取请求类型,将数据转换
let contentType = headers["Content-Type"] || headers.post["Content-Type"] || headers.common["Content-Type"];
if (contentType.includes("urlencoded")) return Qs.stringify(data);
if (contentType.includes("json")) return JSON.stringify(data);
return data;
}
// 请求拦截器
axios.interceptors.request.use((config) => {
// 一般在这里做携带token做身份校验
return config;
})
// 相应拦截器
axios.interceptors.response.use((result) => {
return result.data;
}, (reason) => {
let response = reason.response;
if (response) {
// 说明服务器有返回,但是状态码校验没通过
switch (response.status) {
case "404":
// 做相应的提示
break;
}
} else {
if (reason.code == "ECONNABORTED") {
// 说明请求被中断或者超时
}
if (!navigator.onLine) {
// 说明断网了,做断网提示
}
}
//因为还要向下传递,所以返回失败的promise实例
return Promise.reject(reason);
})
在接口的很多配置都差不多的情况下只是用
axios来配置可以(100个接口有90多个是一样的配置,其他的在请求的时候自己加上不同的配置把默认的覆盖就行了) 但是如果100个请求有一半使用相同的,另一半使用另外一副相同的配置,这个时候可以通过axios.create创建实例来进行分开设置默认配置
let instance_1 = axios.create();
instance_1.defaults.xxx=xxx;
export default instance_1
let instance_2 = axios.create();
instance_2.defaults.xxx=xxx;
export default instance_2
axios的请求失败
- 网络层面的失败:断网,导致没有完成一个
http事务; axios层面的失败:完成了http事务,请求有返回,但是可能校验没通过;或者是请求中断和超时;- 业务层面的失败:一般返回信息都有一个
code标识,可以根据这个判断是否成功获取道数据。