axios的调用-index.html
- axios的调用有不同的形式,01. axios(config) 02. axios.method(url, data? , config? )
- 要实现一个函数方法同时拥有属性,以下实现了一个工具类utils.extend
<script type="text/javascript" src="./myaxios.js"></script>
<body>
<button class="btn">点我发送请求</button>
<script>
document.querySelector('.btn').onclick = function() {
// 分别使用以下方法调用,查看myaxios的效果
axios.get('/getAxios?name=xiaoxiao').then(res => {
console.log('getAxios 成功响应', res);
}, err => {})
// axios.post('/postAxios', {
// name: '小美post'
// }).then(res => {
// console.log('postAxios 成功响应', res);
// })
// axios({
// method: 'get',
// url: '/getAxios'
// }).then(res => {
// console.log('getAxios 成功响应', res);
// })
}
</script>
</body>
</html>
myaxios.js实现axios和axios[method]
- 要实现axios方法,axios.get, axios.post …方法
- eg: function axios(){}; axios[‘get’] = function(){}…
// 工具方法,实现b的方法混入a;
const utils = {
extend(a,b, context) {
for(let key in b) {
if (typeof b[key] === 'function') {
a[key] = b[key].bind(context);
}
}
}
}
// 定义Axios类,实现一个request方法,该方法会执行ajax请求。最终返回的就是Axios实例上的request方法。
class Axios {
constructor() {
this.test = 'zml'
}
request(config) {
console.log('执行request方法, this.test:'+this.test);
return new Promise(resolve => {
const {url = '', method = 'get', data = {}} = config;
// 发送ajax请求
const xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.onload = function() {
console.log(xhr.responseText)
resolve(xhr.responseText);
}
xhr.send(data);
})
}
}
// 定义get,post...方法,挂在到Axios原型上
const methodsArr = ['get', 'delete', 'head', 'options', 'put', 'patch', 'post'];
methodsArr.forEach(met => {
Axios.prototype[met] = function() {
console.log('执行'+met+'方法');
// 处理单个方法
if (['get', 'delete', 'head', 'options'].includes(met)) { // 2个参数(url[, config])
return this.request({
method: met,
url: arguments[0],
...arguments[1] || {}
})
} else { // 3个参数(url[,data[,config]])
return this.request({
method: met,
url: arguments[0],
data: arguments[1] || {},
...arguments[2] || {}
})
}
}
})
// 最终导出axios的方法-》即实例的request方法
function CreateAxiosFn() {
let axios = new Axios();
let req = axios.request.bind(axios);
// 混入方法, 处理axios的request方法,使之拥有get,post...方法
utils.extend(req, Axios.prototype, axios)
utils.extend(req, axios)
return req;
}
// 得到最后的全局变量axios
let axios = CreateAxiosFn();
带拦截器的调用- index.html
<script>
// 拦截器
axios.interceptors.request.use(function (config) {
console.log('拦截😊1');
return config;
}, function (error) {
return Promise.reject(error);
});
axios.interceptors.request.use(function (config) {
console.log('拦截2🏀');
return config;
}, function (error) {
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
console.log('响应拦截1🌹',response);
return response;
}, function (error) {
return Promise.reject(error);
});
</script>
axios实现拦截器
- 定义一个拦截器管理器,成对(一组成功和失败为一对)存储拦截器方法
// 第二步,实现拦截器
class InterceptorsManage {
constructor() {
this.handlers = [];
}
use(fullfield, rejected) {
this.handlers.push({
fullfield,
rejected
})
}
}
- 构造函数Axios初始化时候定义属性: interceptors
class Axios {
constructor() {
this.test = 'zml'
this.interceptors = {
request: new InterceptorsManage,
response: new InterceptorsManage
}
}
}
- request方法调用时候,组装(拦截器+请求方法)队列,之前的请求方法,提取出去。
request(config) {
// 拦截器和请求组装队列
let chain = [this.xhrFn.bind(this), undefined] // 成对出现的,失败回调暂时不处理
// 请求拦截
this.interceptors.request.handlers.forEach(interceptor => {
chain.unshift(interceptor.fullfield, interceptor.rejected)
})
// 响应拦截
this.interceptors.response.handlers.forEach(interceptor => {
chain.push(interceptor.fullfield, interceptor.rejected)
})
console.log(chain);
}
xhrFn(config) {
console.log('执行request方法, this.test:'+this.test);
return new Promise(resolve => {
const {url = '', method = 'get', data = {}} = config;
// 发送ajax请求
const xhr = new XMLHttpRequest();
xhr.open(method, url, true);
xhr.onload = function() {
console.log(xhr.responseText)
resolve(xhr.responseText);
}
xhr.send(data);
})
}
request(config) {
// ...组装队列方法
console.log(chain);
// 执行队列,每次执行一对,并给promise赋最新的值
let promise = Promise.resolve(config);
while(chain.length > 0) {
promise = promise.then(chain.shift(), chain.shift())
}
return promise;
}
// 方法也要混入进去
const utils = {
extend(a,b, context) {
for(let key in b) {
if (b.hasOwnProperty(key)) {
if (typeof b[key] === 'function') {
a[key] = b[key].bind(context);
} else {
a[key] = b[key]
}
}
}
}
}
function CreateAxiosFn() {
let axios = new Axios();
let req = axios.request.bind(axios);
// 混入方法, 处理axios的request方法,使之拥有get,post...方法
utils.extend(req, Axios.prototype, axios)
// 混入属性,处理axios的request方法,使之拥有axios实例上的所有属性
utils.extend(req, axios)
return req;
}
完整代码链接
github地址