axios从入门到源码分析
.axios是什么?
axios:基于promise封装的ajax库,基于这个类库发送ajax请求,默认就是基于promise管理的,核心还是XMLHttpRequest
axios中GET系列的使用方法?
1.首先需要导入axios对应插件:
npm i axios
<script src="node_modules/axios/dist/axios.min.js"></script>
2.GET系列 axios.get([url],[config]) 请求URL地址、配置项
axios.get/head/delete/options/post/put/patch 发送对应类别请求的方法
[url]: 放我们请求资源的对应接口路径,==不带参数==
[config] :用来配置请求信息,是一个对象类型,==每个属性按照键值对的形式配置==
我们配置的这些属性实际上是在给这次请求的xhr实例设置私有属性,不要以为都是在给请求头设字段。
1. params:[string/object] 基于问号参数方案,需要传递给服务器的信息
如果传递的是个对象,axios内部会把对象变为 xxx=xxx&xxx=xxx 这样的字符串,然后基于问号参数传递给服务器;如果写的是一个字符串,则变为 0=字符串 的方式传递给服务器;我们一般都使用对象的方式!!
2. timeout:[number]` :请求超时时间,数字类型但为是==ms==
3. withCredentials:[boolean] :==默认为false==,true:表示允许跨域携带资源凭证,false:表示不允许
4.responseType:[string] :把服务器返回的结果转为对应的数据格式,默认是`json
(==服务器返回的结果,我们都把它转为json对象==),
还有其他类型:'arraybuffer/blob/document/json/text/strem';
5.onUploadProgress:[function]: 监听文件上传进度
6.baseUrl:[string] :配置请求地址的前缀
7.validateStatus:[function] :里面是一个函数,函数中的return可以配置`
status`决定状态值在什么范围才算请求成功,默认2xx为请求成功
8. **headers:{"Name":"lisa"}:** 可以通过headers给请头添加我们想传的数据
axios中POST系列的使用方法?
1.首先需要导入axios对应插件:
npm i axios
<script src="node_modules/axios/dist/axios.min.js"></script>
2.==axios中post的创建方式==:axios.post([url],[data],[config]);对应的put/patch方法
-
- url:字符串类型,请求的目标路径
-
- [data]:可以是字符串类型,可以对象类型,post中请求体的信息,如同xhr.send(),中传的数据,但一般不会传字符串。
-
- [config]:**对象类型,**配置请求的配置项
axios中POST请求的请求主体
-
data就是请求体信息:发送之前,会在内部默认处理称为==JSON字符串==,再传给服务器
-
如果服务器想要的不是JSON字符串,可以将[data]值设置为服务器想要的字符串。
-
如果服务器想要的是urlencoded字符串,我们有两种方式做处理:
方式一:【引入Qs库】,基于Qs.stringify/parse做处理:axios.post([url],Qs.stringify(data),[config]);
Qs.stringify(data):将对象转为urlencoded字符串
Qs.parse(data):将urlencoded字符串转为对象
方式二:使用transformRequest:function ([data],[heders]){return xxx} 的方式,自行改成想要的格式。
-
==axios内部做了一个非常有用的事情==:根据我们传递给服务器的内容格式,自动帮我们设置请求头中的 Content-Type ,让其和传递的格式相匹配「MIME类型」不需要设置headers
-
- urlencoded格式字符串 : Content-Type:'application/x-www-form-urlencoded'
-
- json格式字符串 :Content-Type:'application/json'
-
- FormData格式对象: Content-Type:'multipart/form-data'
Qs.stringify(data):将对象转为urlencoded字符串 必须是纯对象
对象分为几大类?
-
对象类型「引用数据类型」
-
- 标准普通对象 object
-
- 标准特殊对象 Array、RegExp、Date、Math、Error……
-
- 非标准特殊对象 Number、String、Boolean……
-
- 可调用/执行对象「函数」function
加密:md5
加密:对称加密(可逆转加密,加密完可以解密,)一般自己设定规则
非对称加密(不可逆转的加密)一般使用md5加密
.基于axios发送的请求,返回结果都是promise实例
-
- 数据请求成功会让promise状态为成功,promise值就是从服务器获取的结果
-
- 数据请求失败会让promise状态为失败
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做get请求时存在的三种错误情况?
==有响应体== :返回的错误对象中有状态码:response->status,没有code
- ==无响应体==:
-
timeout:请求超时或被中断,没有状态码,有code属性:code:"ECONNABORTED" response:undefined
-
navigator.onLine=false(断网)时:没有状态码,也没有code和response,只能用navigator.onLine=false判断。
.axios的get和post请求另一种写法?
axios({
method: 'get',
url:'http://127.0.0.1:9999/user/list',
params:{id:1},//重点,get方法中用params
headers:{}
}).then(res=>{
console.log(res);
})
axios({
method: 'post',
url:'http://127.0.0.1:9999/user/list',
data:{id:1},//重点,post方法中才能有data
headers:{}
}).then(res=>{
console.log(res);
})
二次封装
==提取公共配置==:axios的二次封装就是将所有请求的公共部分提取到一个默认的js文件中,所有的请求都会遵循这个默认配置文件。
*默认配置 :axios.defaults.xxx;->xxx:是能够配置的配置项,如timeout
==单独配置== :单独写的请求配置,优先级高于公共配置
axios.defaults.baseURL = 'http://127.0.0.1:9999';//设置公共 前缀路径
axios.defaults.transformRequest = data => {//设置公共 转换请求体格式
if (isPlainObject(data)) return Qs.stringify(data);
return data;
};
axios.defaults.timeout = 60000;//设置公共 请求超时时间
axios的请求、响应拦截器怎么使用?
- 请求/响应拦截器**:axios.interceptors.request/response
-
- 基于拦截器进行公共部分提取
-
- 请求拦截器:发生在 “配置项准备完毕” 和 “发送请求” 之间
-
- 响应拦截器:发生在 “服务器返回结果” 和 “业务代码自己处理 .then” 之间
//请求拦截
axios.interceptors.request.use(config => {
// config对象包含的就是准备好的配置项,最后返回啥配置,就按照这些配置发请求
return config;
});
-
//响应拦截:如果成功就将结果返回给用户,如果失败,进行处理再返回 axios.interceptors.response.use(response => { // 请求成功:把响应主体信息返回给业务层去使用 return response.data; }, reason => { // 请求失败:根据不同的失败原因做不同的提示 if (reason && reason.response) { // @1 有返回结果,只不过状态码不对 let {status} = reason.response; switch (+status) {//switch是做===比较 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); });
### Fetch的使用
ES6新增的一种API Fetch,==是浏览器原生自带的==,核心不是XMLHttpRequest,是基于全新的通信机制实现的[本身是基于promise管理的]
```cobol
fetch('http://localhost:9999/job/list',{
method:'GET',
headers:{},//请求头信息
//必须是字符串
// body:JSON.stringify({id:0})//请求体中的参数,GET/HEAD/OPtions/DELETE方法没有请求体,不能有body
}).then(function(response){
console.log(response);//获取的是一个响应信息的对象,看不到真正的响应体
return response.json(); //想要获取响应体的信息,需要调用对应格式的response.xxx()方法
}).then(function(value){
console.log(value);
})
注意点
-
- GET/DELETE/OPTIONS/HEAD方法中不能存在body。
-
- fetch得到的结果是一个Promise对象,可以调用then方法PromiseResult是响应的信息,但找不到响应体信息。
-
- 想要获取响应体信息需要调用
result对应数据格式的方法,比如想获取json格式的响应数据:result.json()/result.text()/result.formdata()/...
- 想要获取响应体信息需要调用
-
- ==
result.json等格式获取方法只能使用一次,且只能有一种==
- ==
axios和Fetch的区别?
-
他俩都是发送请求的
-
- axios是基于promise封装的ajax类库
-
- fetch是浏览器原生的API
-
- 传参字段不一样,axios是放在params或者data里,fetch是放在body里
-
- node环境中不支持fetch,需要引入node-fetch文件才能支持
-
- axios中的配置和拦截器等功能,fetch中都没有。
面试题:ajax、$ajax、axios、fetch的区别
==ajax:== 原生的ajax,依赖XMLHttpRequest,再基于ajax的四步操作,实现从服务器获取数据
- ==$ajax:== 是JQ类库对原生ajax的封装,基于回调函数封装的ajax类库
-
- 核心:XMLHttpRequest
-
- 当请求成功,触发succes回调函数执行,在这个回调函数可以拿到从服务器获取的数据
-
- 弊端:在akax的串行中,容易产生回调地狱
- axios: 基于promise封装的ajax库
-
- 核心也是XmlHTTPRequest
-
- 基于promise更好的管理一部编程
-
- 每一次基于axios发送请求,都会返回一个promise实例;
-
- ==请求成功==:实例为fulfilled,但是从服务器获取的结果
-
- ==请求失败==:实例为rejected,值是失败的原因
-
fetch :ES6新增的方法:
-
- 核心告别了XMLHttpRequest的时代,基于新的通信机制实现客户端和服务器端的数据传输
-
- 默认就是基于promise管理的
-
- 缺点:不兼容IE浏览器(而且@bable/poly没有实现它)
QS库
安装qs库 $ yarn add qs
引入:
Qs.stringify(obj):把obj对象转换为urlencoded格式的字符串
"xxx=xxx&xxx=xxx"
MIME:application/x-www-form-urlencoded
Qs.parse(str):把urlencoded格式的字符串变为对象
浏览器内置的JSON对象
JSON.stringify(obj):把obj对象转换为json格式的字符串
'{"name":"zhufeng",...}'
MIME:application/json
JSON.parse(str):把json格式的字符串转换为对象