axios
axios(阿克晓奥丝,爱可信)
axios:基于promise封装的ajax库,基于这个类库发送ajax请求,默认就是基于promise管理的
核心还是XMLHttpRequest
官网
axios.get/head/delete/options/post/put/patch 发送对应类别请求的方法
GET系列:axios.get([url],[config]) 请求URL地址、配置项
POST系列:axios.post([url],[data],[config]) 请求URL地址、请求主体信息、配置项
配置项:
[object]都是plain object纯粹对象
-
params:[string/object] 基于问号参数方案,需要传递给服务器的信息,如果传递的是个对象,axios内部会把对象变为 xxx=xxx&xxx=xxx 这样的字符串,然后基于问号参数传递给服务器;如果写的是一个字符串,则变为 0=字符串 的方式传递给服务器;我们一般都使用对象的方式!!
-
headers:[object] 设置请求头信息,例如:headers:{ 'Content-Type': 'application/x-www-form-urlencoded' } 设定客户端传递给服务器的内容格式是urlencoded格式
-
timeout:[number] 设置超时时间 写零是不设置,单位是MS
-
withCredentials:[boolean] 跨域请求中是否允许携带资源凭证 默认是false
-
responseType:[string] 把服务器返回的结果转换为对应的数据格式 默认是json「服务器返回的结果,我们都把其变为JSON格式的对象」、'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
-
onUploadProgress:[function] 监听文件上传的进度
-
baseURL:[string] 请求地址的公共前缀
-
transformRequest:[function] POST系列请求,对请求主体的数据进行格式化处理
-
validateStatus:[function] 预设服务器返回的HTTP状态码是多少才算请求成功,默认是以2开始的算成功
基于axios发送的请求,返回结果都是promise实例
- 数据请求成功会让promise状态为成功,promise值就是从服务器获取的结果
- 数据请求失败会让promise状态为失败
- 服务器有响应信息,但是状态码不是以2开始的:reason对象中有response属性,存储服务器返回的信息
- 请求超时或者被中断 code:"ECONNABORTED" response:undefined
- 断网了 navigator.onLine=false
axios.get('http://127.0.0.1:9999/user/list', {
timeout: 1,
params: {
departmentId: 0,
search: ''
}
}).then(response => {
console.log('请求成功:', response);
// response对象
// + status/statusText HTTP状态码及其描述
// + request 原生的XHR对象
// + headers 存储响应头信息(对象)
// + config 存储发送请求时候的相关配置项
// + data 存储响应主体信息
return response.data;
}).then(value => {
console.log('响应主体信息:', value);
}).catch(reason => {
console.log('请求失败:');
console.dir(reason);
});
AXIOS处理POST系列请求:
@1 我们DATA(请求主体)写的是一个对象,内部默认处理成为JSON格式的字符串,然后传递给服务器「因为:用AJAX基于请求主体传递给服务器的内容格式有限制 字符串{URLENCODED格式、JSON格式、普通...}、ArrayBuffer、Blob、FormData格式对象」
@2 如果服务器要求传递的格式不是JSON字符串,我们可以给DATA设置值是自己想要的字符串格式
如果要求传递的是 urlencoded 格式字符串,我们可以基于 Qs.stringify/parse 进行处理「引入QS库」
有一个配置项专门是用来处理POST请求,请求主体的数据格式的:transformRequest
- data传递的依然是个对象格式「常用写法」
- transformRequest:(data,headers)=>
AXIOS内部做了一个非常有用的事情:根据我们传递给服务器的内容格式,自动帮我们设置请求头中的 Content-Type ,让其和传递的格式相匹配「MIME类型」
urlencoded格式字符串 Content-Type:'application/x-www-form-urlencoded'
json格式字符串 Content-Type:'application/json'
FormData格式对象 Content-Type:'multipart/form-data'
...
const qs = require('querystring');
// 验证是否为纯粹的对象
const isPlainObject = function isPlainObject(obj) {
let proto, Ctor;
if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
proto = Object.getPrototypeOf(obj);
if (!proto) return true;
Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
return typeof Ctor === "function" && Ctor === Object;
};
axios.post('http://127.0.0.1:9999/user/login', {
account: '18310612838',
password: md5('1234567890')
}, {
transformRequest: data => {
// data:我们传递的这个对象
// return什么值,就是把其基于请求主体专递给服务器
if (isPlainObject(data)) return qs.stringify(data);
return data;
}
}).then(response => {
return response.data;
}).then(value => {
console.log('请求成功', value);
}).catch(reason => {
// 根据不同的情况做不同提示interceptors
});
项目中对 axios 的封装使用
Axios的二次配置:把多个请求之间公共的部分进行提取,后期在业务中再次发送数据请求,公共部分无需再次编写
- axios.defaults.xxx
- axios.interceptors.request/response 请求/响应拦截器
// 验证是否为纯粹的对象
const isPlainObject = function isPlainObject(obj) {
let proto, Ctor;
if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
proto = Object.getPrototypeOf(obj);
if (!proto) return true;
Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
return typeof Ctor === "function" && Ctor === Object;
};
// 请求地址的公共前缀:这样后期再发请求的时候,URL地址中公共前缀部分就不需要写了
// 原理:请求URL地址不含“http(s)://”,发送请求的时候会把baseURL拼上去,然后再发请求;如果自己的URL包含了“http(s)://”这个部分,则以自己的为主,就不在去拼接baseURL了;
axios.defaults.baseURL = 'http://127.0.0.1:9999';
// 根据当前服务器的要求,对于POST系列请求,请求主体传递给服务器的格式都是:urlencoded格式字符串
axios.defaults.transformRequest = data => {
if (isPlainObject(data)) return Qs.stringify(data);
return data;
};
// 其它可提取的公共配置部分
axios.defaults.timeout = 60000;
axios.defaults.withCredentials = true;
axios.defaults.validateStatus = status => {
// 校验服务器返回状态码为多少才算请求成功:默认以2开始才算
return status >= 200 && status < 400;
};
// 基于拦截器进行公共部分提取
// + 请求拦截器:发生在 “配置项准备完毕” 和 “发送请求” 之间
// + 响应拦截器:发生在 “服务器返回结果” 和 “业务代码自己处理 .then” 之间
axios.interceptors.request.use(config => {
// config对象包含的就是准备好的配置项,最后返回啥配置,就按照这些配置发请求
return config; // return new Promise((res, rej) => {}) 这里也可以返回一段异步代码
});
axios.interceptors.response.use(response => {
// 请求成功:把响应主体信息返回给业务层去使用
return response.data;
}, reason => {
// 请求失败:根据不同的失败原因做不同的提示
if (reason && reason.response) {
// @1 有返回结果,只不过状态码不对
let {
status
} = reason.response;
switch (+status) {
case 403:
alert('服务器不爱搭理你~~');
break;
case 404:
alert('你傻啊,地址都错了~~');
break;
case 500:
alert('服务器开小差了~~');
break;
}
} else {
// @2 请求超时或者中断
if (reason && reason.code === "ECONNABORTED") {
alert('请求超时或者被中断了~~');
}
// @3 断网
if (!navigator.onLine) {
alert('当前网络出问题了~~');
}
}
// 统一失败提示处理完,到业务代码处,我们还是要失败的状态,这样才能继续做一些自己单独想做的失败处理
return Promise.reject(reason);
});

浙公网安备 33010602011771号