1. Axios 的使用
www.axios-js.com/zh-cn/docs/
axios:基于promise封装的ajax库,基于这个类库发送ajax请求,默认就是基于promise管理的,核心还是XMLHttpRequest
axios.get/head/delete/options 发送对应类别请求的方法
1. GET系列
//axios.get(url[,config]) 返回Promise的实例,可以用then catch async await
// url: 请求网址 必须写
// config: 配置项(对象) 可有可无
// baseURL:基础路径
// params: get类请求的参数 对象(自动将参数拼接url后面)
// timeout:请求超时时间
// withCredentials: false 是否允许携带跨域资源凭证 默认false
// responseType: 'json', 自动转化返回的数据格式 默认json
// validateStatus: function (status) {
// return status >= 200 && status < 300; // default
// },状态码成功的范围
// onUploadProgress:监控文件上传进度
// onDownloadProgress:监控文件下载进度
GET系列 axios.get([url],[config]) 请求URL地址、配置项
axios.get("/api/articleList",{
baseURL:"http://localhost:8888",
params:{
date:"2021-05-21"
},
timeout:1000,
withCredentials:false,
validateStatus: function (status) {
return status >= 200 && status < 400;
}
}).then(value=>{
console.log(value);
})
配置项:
- params:[string/object] 基于问号参数方案,需要传递给服务器的信息;
如果传递的是个对象,axios内部会把对象变为 xxx=xxx&xxx=xxx 这样的字符串,然后基于问号参数传递给服务器;如果写的是一个字符串,则变为 0=字符串 的方式传递给服务器;我们一般都使用对象的方式!!
axios.get('http://127.0.0.1:9999/user/list', {
params:"zhufeng"
})
axios.get('http://127.0.0.1:9999/user/list', {
params: {
departmentId: 0,
search: ''
}
})
2.timeout:[number] 设置超时时间 写零是不设置,单位是MS
axios.get('http://127.0.0.1:9999/user/list', {
params: {
departmentId: 0,
search: ''
},
timeout:0
})
3. withCredentials:[boolean] 跨域请求中是否允许携带资源凭证 默认是false<br /> 4. responseType:[string] 把服务器返回的结果转换为对应的数据格式 默认是json「服务器返回的结果,我们都把其变为JSON格式的对象」、'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'<br /> 5. onUploadProgress:[function] 监听文件上传的进度<br /> ----<br /> 6. baseURL:[string] 请求地址的公共前缀<br /> 7. validateStatus:[function] 预设服务器返回的HTTP状态码是多少才算请求成功,默认是以2开始的算成功
2.POST系列
axios.post/put/patch 发送对应类别请求的方法
POST系列 axios.post([url],[data],[config]) 请求URL地址、请求主体信息、配置项
axios.post(url,data[,config]) 返回Promise的实例
url: 请求网址 必须写
data: post类传递的参数 可有可无 对象 字符串
config: 配置项(对象) 可有可无
baseURL:基础路径
timeout:请求超时时间
withCredentials: false 是否允许携带跨域资源凭证 默认false
responseType: 'json', 自动转化返回的数据格式 默认json
validateStatus: function (status) {
return status >= 200 && status < 300; // default
},状态码成功的范围
onUploadProgress:监控文件上传进度
onDownloadProgress:监控文件下载进度
headers:设置请求头信息
(大多数情况下,根据参数传递的格式,自动设置Content-Type的值)
transformRequest: 在发送参数之前,可以统一对参数进行处理
//问题:参数是对象格式,需求urlencoded格式
//方法1:参数直接改为urlencoded 不推荐
axios.post("/user/login",
"account=18310612838&password=" + md5("1234567890"), {
baseURL: "http://127.0.0.1:9999",
// headers: {
// "Content-Type": "application/x-www-form-urlencoded"
// },
timeout: 1000,
withCredentials: false,
validateStatus: function(status) {
return status >= 200 && status < 400; // default
}
}).then(value => {
console.log(value.data);
})
//方法2:参数直接传对象
axios.post("/user/login", {
account: "18310612838",
password: md5("1234567890")
}, {
baseURL: "http://127.0.0.1:9999",
timeout: 1000,
withCredentials: false,
validateStatus: function(status) {
return status >= 200 && status < 400; // default
},
transformRequest: function(data) { //只支持 post put patch
//console.log(data);
//Qs.stringify() 将普通对象转化为urlencoded格式
//console.log(Qs.stringify(data));
return Qs.stringify(data); //return的结果,就是新参数的值,格式
}
}).then(value => {
console.log(value.data);
})
请求主体信息:
1. 我们DATA(请求主体)写的是一个对象,内部默认处理成为JSON格式的字符串,然后传递给服务器「因为:用AJAX基于请求主体传递给服务器的内容格式有限制 字符串{URLENCODED格式、JSON格式、普通...}、ArrayBuffer、Blob、FormData格式对象」
axios.post('http://127.0.0.1:9999/user/login', {
account: '18310612838',
password: '1234567890'
})
- 如果服务器要求传递的格式不是JSON字符串,我们可以给DATA设置值是自己想要的字符串格式
axios.post('http://127.0.0.1:9999/user/login',
`account=18310612838&password=${md5("1234567890")}`)

如果要求传递的是 urlencoded 格式字符串,我们可以基于 Qs.stringify/parse 进行处理「引入QS库」<br />
let data={
account: '18310612838',
password: '1234567890'
}
axios.post('http://127.0.0.1:9999/user/login',Qs.stringify(data));
还有一种方法:transformRequest
- headers:[object] 设置请求头信息,例如:headers:{ 'Content-Type': 'application/x-www-form-urlencoded' } 设定客户端传递给服务器的内容格式是urlencoded格式
axios.post("http://127.0.0.1:9999/user/login",{
account:"13041086186",
password:md5("1234567890")
},{
transformRequest: data => {
if (isPlainObject(data)) return Qs.stringify(data);
return data;
},
headers:{ 'Content-Type': 'application/x-www-form-urlencoded'}
})
配置项:
1.与GET系列一样,但是没有params
2.transformRequest:[function] POST系列,对请求主体的数据进行格式化处理
专门是用来处理POST请求,请求主体的数据格式的<br /> + data传递的依然是个对象格式「常用写法」<br /> + transformRequest:(data,headers)=>{ return xxx; }
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;
}
})
// 对象.proto===Object.prototype Object.create(null)是纯粹对象
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;
};
-------------------注释
// 定义一个函数 isPlainObject,用于判断传入的参数是否是一个普通对象
const isPlainObject = function isPlainObject(obj) {
let proto, Ctor; // 声明两个变量用于存储对象的原型和构造函数
// 如果传入的参数是 null、undefined 或者不是对象类型,则直接返回 false
if (!obj || Object.prototype.toString.call(obj) !== "[object Object]") return false;
// 获取传入对象的原型
proto = Object.getPrototypeOf(obj);
// 如果原型不存在,则说明传入的对象是一个普通对象,直接返回 true
if (!proto) return true;
// 判断原型对象是否有 constructor 属性,并获取该属性的值赋给 Ctor
Ctor = proto.hasOwnProperty('constructor') && proto.constructor;
// 判断 Ctor 是否是一个函数且是否等于 Object 构造函数,如果是则返回 true,否则返回 false
return typeof Ctor === "function" && Ctor === Object;
};
3.其他:
1.加密:md5
2. AXIOS内部做了一个非常有用的事情:
根据我们传递给服务器的内容格式,自动帮我们设置请求头中的 Content-Type ,让其和传递的格式相匹配「MIME类型」
urlencoded格式字符串 Content-Type:'application/x-www-form-urlencoded'
json格式字符串 Content-Type:'application/json'
FormData格式对象 Content-Type:'multipart/form-data'
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 => {
// 根据不同的情况做不同提示
});
3.基于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({
method: 'get',
url:'http://127.0.0.1:9999/user/list',
params:{id:1},
headers:{},
...
}).then(res=>{
console.log(res);
})
axios({
method: 'post',
url:'http://127.0.0.1:9999/user/list',
data:{id:1},
headers:{},
....
}).then(res=>{
console.log(res);
})
2. Axios的二次配置
把多个请求之间公共的部分进行提取,后期在业务中再次发送数据请求,公共部分无需再次编写
- axios.defaults.xxx 默认配置
+ axios.interceptors.request/response 请求/响应拦截器
1.请求地址的公共前缀:这样后期再发请求的时候,URL地址中公共前缀部分就不需要写了
原理:请求URL地址不含“http(s)://”,发送请求的时候会把baseURL拼上去,然后再发请求;如果自己的URL包含了“http(s)://”这个部分,则以自己的为主,就不在去拼接baseURL了;
axios.defaults.baseURL = 'http://127.0.0.1:9999';
2.根据当前服务器的要求,对于POST系列请求,请求主体传递给服务器的格式都是:urlencoded格式字符串
axios.defaults.transformRequest = data => {
if (isPlainObject(data)) return Qs.stringify(data);
return data;
};
3.配置公共超时时间
axios.defaults.timeout = 60000;
4.配置公共跨域请求中是否允许携带资源凭证(允许)
axios.defaults.withCredentials = true
5.校验服务器返回状态码为多少才算请求成功:默认以2开始才算
axios.defaults.validateStatus = status => {
return status >= 200 && status < 400;
};
6.基于拦截器进行公共部分提取
+ 请求拦截器:发生在 “配置项准备完毕” 和 “发送请求” 之间
+ 响应拦截器:发生在 “服务器返回结果” 和 “业务代码自己处理 .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) {
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);
});
3.Fetch 的使用
developer.mozilla.org/zh-CN/docs/…
www.ruanyifeng.com/blog/2020/1…
- omit:从不发送cookie。
- same-origin:如果URL与调用脚本位于相同的源,则发送用户凭证(cookie,基本http认证等)。
- include:始终发送用户凭据(cookie,基本http认证等),甚至用于跨源调用。
fetch('http://127.0.0.1:9999/user/list?departmentId=0&search=',{
method: 'GET',
headers: {},//请求头信息
// 必须是字符串 或者 对象
// body: JSON.stringify({id:1})// post参数
}).then(function(response) {
//需要使用fetch提供的json方法转化一下
//注意:.json()和.text()方法只能执行一次
//console.log(response.json());
//数据放在promise,需要再.then
return response.json();
}).then(function(myJson) {
console.log(myJson);
});
fetch('./data.json').then(response => {
// response中包含了服务器返回的信息:响应主体信息response.body「ReadableStream可读流信息」,我们需要把可读流信息变为指定的格式
// + Response.prototype.json/text/blob(文件流格式)/arrayBuffer(buffer)...
// + 执行这些方法中的任何一个,返回结果都是一个promise实例:如果可以把响应主体信息正常转换为指定的格式,则promise的状态是fulfilled、值是转换为的数据内容,如果不能正常转换,则状态是失败的...
// + 一但执行了其中的一个方法,再执行其他方法,会出问题
return response.json();
}).then(value => {
console.log(value);
});
fetch和axios的区别
他俩都是发送请求的
axios是基于promise封装的ajax类库
fetch是浏览器原生的API
传参字段不一样,axios是放在params或者data里,fetch(post)是放在body里
node环境中不支持fetch,需要引入node-fetch文件才能支持
axios中的配置和拦截器等功能,fetch中都没有。