axios
基础使用
Axios 才是类
把常用的http请求方式封装成了方法
axios.get(url, config)
axios.post(url, data, config) data:即请求主体
get
如果直接用axios,它是做了一层封装的。
config:发送请求时配置的那些配置项
data:响应主体
headers:响应头
status:响应码
statusText:响应信息描述
request:xhr实例对象
get缓存需要自己手动加Math.random或+new Date
axios.get('https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list',{
params:{a:'a',b:'b'},
headers:{'X-Csrf':'xxx'}
}).then(result=>{
console.log('result===');
console.log(result);
return result.data;
}).catch(error=>{
console.log('error===');
console.log(error);
}).then(data=>{
console.log(data);
})
post
transformRequest:针对post请求的请求主体做格式化处理
console.dir(axios);
axios.post('https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list',{
a:'a',b:123
},{
headers:{
'X-Csrf':'xxx',
'Content-Type': ' application/json',
},
transformRequest:function(data){
console.log('data');
console.log(data);
return Object.entries(data).map(o=>`${o[0]}=${o[1]}`).join('&');
// return JSON.stringify(data);
}
}).then(result=>{
console.log('result===');
console.log(result);
return result.data;
}).catch(error=>{
console.log('error===');
console.log(error);
}).then(data=>{
console.log(data);
})
如果不传就是这种格式
默认配置项和拦截器
promise链的知识:catch中抛异常,会走下一个catch
例如:
所有的post都需要transformRequest、url前面都是一样的……这些都可以做成公共的
默认的公共的通用的东西都提前配置好。全局的axios默认配置项
-
拦截器request/response.use和promise用法一致;
-
默认配置项覆盖默认值
let http=axios.create({
baseURL:'https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee',
withCredentials:true,
headers:{
'Content-Type':'application/x-www-form-urlencoded'
},
})
// 请求拦截器:把body序列化成form-urlencoded格式
http.interceptors.request.use(function(config){
console.log('interceptors.request===');
console.log(config);
if(config.data){
config.data=Object.entries(config.data).map(o=>`${o[0]}=${o[1]}`).join('&');
}
return config;
})
// 响应拦截器
http.interceptors.response.use(function(response){
console.log('interceptors.reponse===');
console.log(response);
// 只返回响应主体
return response.data;
},function(error){
return Promise.reject(error)
})
http.post('/cgi/add',{a:'a',b:111}).then(result=>{
console.log('result===');
console.log(result);
}).catch(error=>{
console.log('error===');
console.log(error);
})
axios和promise中的重点知识
promise梳理
new Promise时需要一个executor,参数为resolve,reject。new的时候executor就会执行
resovle(x):把状态改为fulfilled,x赋值为value
reject(x):把状态改为rejected,x赋值为value
原型上提供了then catch finally 3个方法,供实例来用
.then又返回了一个全新的promise实例,代码执行不报错,后面走then;
如果当前then返回的是promise对象,那么就会以这个promise的状态为准;
then若没设置成功/失败回调,就沿着then链顺延;
全局API:
Promise.resolve
Promise.reject
Promise.all
Promise.allSettled
Promise.race
自己封装axios
这个库要具备的功能
类库:构造函数
策略:想把它当普通函数执行,但是还能创建出它的一个实例:
创建第2个函数init,每次执行都是创建init的一个实例,然后把init.prototype=jquery.prototype
(function(){
class Ajax{
constructor(){
}
}
function _ajax(){
}
_ajax.defaults={
baseURL:'',
timeout:null,
withCredentials:true,
headers:{
'Content-Type':'application/x-www-form-urlencoded'
},
transformRequest:function(data){
return Object.entries(data).map(o=>`${o[0]}=${o[1]}`).join('&')
},
transformResponse:function(response){
return response.data;
},
params:{},
data:{},
}
_ajax.all=function(promiseArr=[]){
return Promise.all(promiseArr);
}
_ajax.get=function(){
}
window._ajax=_ajax;
})()
封装promise版ajax
参数初始化,_init函数
传的时候按3项传,但是最后我们处理成两项;
最后走到MyAjax的时候,永远都只有2个参数;
走到入口的时候完全统一
(function(){
class MyAjax{
constructor(){
}
}
function _ajax(){
}
_ajax.defaults={
baseURL:'',
timeout:null,
withCredentials:true,
headers:{
'Content-Type':'application/x-www-form-urlencoded'
},
transformRequest:function(data){
return Object.entries(data).map(o=>`${o[0]}=${o[1]}`).join('&')
},
transformResponse:function(response){
return response.data;
},
params:{},
data:{},
}
function _init(options={}){
const { headers={} }=options;
_ajax.defaults.headers=Object.assign(_ajax.defaults.headers,headers);
delete options.headers;
_ajax.defaults=Object.assign(_ajax.defaults,options);
}
_ajax.all=function(promiseArr=[]){
return Promise.all(promiseArr);
}
_ajax.get=function(ur,config){
return new MyAjax(url,_init(config));
}
_ajax.post=function(url,data,config){
config.data=data;
return new MyAjax(url,_init(config));
}
window._ajax=_ajax;
})()
promise版本ajax
(function(){
class MyAjax{
constructor(url,options){
this.url=url;
this.options=options;
return this.init()
}
init(){
let {
url,
options:{
headers,
baseURL,
method,
params,
data,
transformRequest,
transformResponse,
validateStatus,
cache=false,
}
}=this;
!Array.isArray(transformResponse)?[]:null;
for(let i=0;i<2;i++){
!typeof transformResponse[i] === 'function'?transformResponse[i]=null:null;
}
return new Promise((resolve,reject)=>{
let xhr=new XMLHttpRequest;
// url处理
if(/^(GET|HEAD|DELETE|OPTIONS)$/i.test(method)){
let query=Object.entries(params).map(o=>`${o[0]}=${o[1]}`).join('&')
url+=`${url.includes('?')?'&':'?'}${query}`
if(!cache){
url+=`${url.includes('?')?'&':'?'}_=${+new Date}`
}
}
xhr.open(method,url);
xhr.onreadystatechange=()=>{
let result=validateStatus(xhr.status);
if(!result){
reject({
status:xhr.status,
statusText:xhr.statusText,
request:xhr,
})
return;
}
if(xhr.readyState===4){
let obj={}
let headers=xhr.getAllResponseHeaders();
headers.split(/\n/).forEach(item=>{
let [key,value]=item.split(': ');
if(key){
obj[key]=value;
}
})
resolve({
status:xhr.status,
statusText:xhr.statusText,
data:JSON.parse(xhr.responseText),
request:xhr,
})
}
}
// 设置请求头
if(headers){
for(let key in headers){
if(headers.hasOwnProperty(key)){
xhr.setRequestHeader(key,encodeURI(headers[key]));
}
}
}
// data处理
if(/^(POST|PUT)$/i.test(method)){
typeof transformRequest==='function'?data=transformRequest(data):null;
}else{
data=null;
}
xhr.send(data);
}).then(...transformResponse)
}
}
function _ajax(){
// return new MyAjax();
}
_ajax.defaults={
baseURL:'',
timeout:null,
withCredentials:true,
headers:{
'Content-Type':'application/x-www-form-urlencoded'
},
transformRequest:function(data){
return Object.entries(data).map(o=>`${o[0]}=${o[1]}`).join('&')
},
transformResponse:[function(response){
return response.data;
},null],
validateStatus:function(status){
return /^(2|3)\d{2}$/.test(status);
},
params:{},
data:{},
}
function _init(options={}){
const { headers={} }=options;
_ajax.defaults.headers=Object.assign(_ajax.defaults.headers,headers);
delete options.headers;
_ajax.defaults=Object.assign(_ajax.defaults,options);
return _ajax.defaults;
}
_ajax.all=function(promiseArr=[]){
return Promise.all(promiseArr);
}
let getArr=['get','delete','head','options'];
getArr.forEach(item=>{
_ajax[item]=function(url,config){
config.method=item;
console.log('get===')
return new MyAjax(url,_init(config));
}
})
let postArr=['post','put'];
postArr.forEach(item=>{
_ajax[item]=function(url,config){
config.method=item;
return new MyAjax(url,_init(config));
}
})
console.dir(_ajax);
window._ajax=_ajax;
})()
_ajax.get('https://mock.mengxuegu.com/mock/6262c4510a65bd50bbd93eee/cgi/list',{
params:{a:'a',b:'b'},
headers:{'X-Csrf':'xxx'}
}).then(result=>{
console.log('result===');
console.log(result);
return result.data;
}).catch(error=>{
console.log('error===');
console.log(error);
})