axios
是基于promise 运行在browser和node环境
基本使用
const btns = document.querySelectorAll("button");
btns[1].onclick = function() {
axios({
method:"POST",
url:"https:/xxx/list",
data:{
owId:"2"
}
}).then(res => {
console.log(res);
})
}
btns[0].onclick = function() {
axios({
method:"Get",
url:"https://xxx/list",
params:{
owId:"2"
}
}).then(res => {
console.log(res);
})
}
其他使用方法
axios.request({
method:"POST",
url:"https://xxx/list",
data:{
Id:"2"
}
}).then(res => {
console.log(res);
})
axios.post("https://xxx/list",{Id:"2"}).then(res => {
})
axios.get("https://xxx/list",{params:{Id:"2"}}).then(res => {
})
resquest配置对象
{
// 请求目标路径
url: '/user',
// 请求的方法
method: 'get', // default
//请求根路径
baseURL: 'https://some-domain.com/api/',
//发送请求前先将数据进行处理,处理后的数据返回给后台
transformRequest: [function (data, headers) {
// Do whatever you want to transform the data
return data;
}],
//响应后结果进行处理
transformResponse: [function (data) {
// Do whatever you want to transform the data
return data;
}],
// 请求头信息: 如果在头部加入 校验信息
headers: {'X-Requested-With': 'XMLHttpRequest'},
// 设置url参数,可以通过对象设置,可以替代:xxx/id=12345
params: {
ID: 12345
},
// 参数序列化,转换成字符串,
// (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
paramsSerializer: function (params) {
return Qs.stringify(params, {arrayFormat: 'brackets'})
},
// form表单提交参数
data: {
firstName: 'Fred'
},
// syntax alternative to send data into the body
// method post
// only the value is sent, not the key
data: 'Country=Brasil&City=Belo Horizonte',
//请求超时时间.
timeout: 1000, // default is `0` (no timeout)
//跨域请求,对cookie是否跨域,如果 true,跨域会携带cookie
withCredentials: false, // default
// 请求适配器
// Return a promise and supply a valid response (see lib/adapters/README.md).
adapter: function (config) {
/* ... */
},
// `auth` indicates that HTTP Basic auth should be used, and supplies credentials.
// This will set an `Authorization` header, overwriting any existing
// `Authorization` custom headers you have set using `headers`.
// Please note that only HTTP Basic auth is configurable through this parameter.
// For Bearer tokens and such, use `Authorization` custom headers instead.
//请求基础验证
auth: {
username: 'janedoe',
password: 's00pers3cret'
},
// `responseType` indicates the type of data that the server will respond with
// options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
// browser only: 'blob'
//响应格式
responseType: 'json', // default
// `responseEncoding` indicates encoding to use for decoding responses (Node.js only)
// Note: Ignored for `responseType` of 'stream' or client-side requests
//响应编码
responseEncoding: 'utf8', // default
// `xsrfCookieName` is the name of the cookie to use as a value for xsrf token
//做请求保护,携带标识
xsrfCookieName: 'XSRF-TOKEN', // default
// `xsrfHeaderName` is the name of the http header that carries the xsrf token value
//做请求保护,携带标识
xsrfHeaderName: 'X-XSRF-TOKEN', // default
// `onUploadProgress` allows handling of progress events for uploads
// browser only
//上传回调
onUploadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
},
// `onDownloadProgress` allows handling of progress events for downloads
// browser only
//下载回调
onDownloadProgress: function (progressEvent) {
// Do whatever you want with the native progress event
},
// `maxContentLength` defines the max size of the http response content in bytes allowed in node.js
//响应体的最大尺寸
maxContentLength: 2000,
// `maxBodyLength` (Node only option) defines the max size of the http request content in bytes allowed
//响应体的最大尺寸
maxBodyLength: 2000,
// `validateStatus` defines whether to resolve or reject the promise for a given
// HTTP response status code. If `validateStatus` returns `true` (or is set to `null`
// or `undefined`), the promise will be resolved; otherwise, the promise will be
// rejected.
//对成功状态
validateStatus: function (status) {
return status >= 200 && status
axios 默认配置(简化代码)
const btns = document.querySelectorAll("button");
//默认配置
axios.defaults.method = "POST";
axios.defaults.baseURL = "https://xxx"
axios.defaults.withCredentials = true;
axios.defaults.timeout = 3000;
btns[1].onclick = function() {
axios({
url:"/list",
data:{
Id:"2"
}
}).then(res => {
console.log(res);
})
}
axios 实例对象(和axios一样,目的可以向不同服务器发送请求,配置不同的配置)
const instance = axios.create({
baseURL:"https://aaa.com",
timeout: 1000,
method:"POST"
})
const instance2 = axios.create({
baseURL:"https://bbb.com",
timeout: 3000,
method:"GET"
})
console.log(instance);
instance({
url:"/list",
data:{
Id:"2"
}
}).then(res => {
})
instance2({
url:"/list",
data:{
Id:"2"
}
}).then(res => {
})
axios 拦截器 interceptors(核心:请求拦截器后进先执行,响应拦截器先进先执行)
// 设置请求拦截器
axios.interceptors.request.use(function (config) {
//修改请求的参数配置
return config;
}, function (error) {
return Promise.reject(error);
});
axios.interceptors.response.use(function (response) {
//处理响应业务
return response;
}, function (error) {
return Promise.reject(error);
});
axios 取消请求
const btns = document.querySelectorAll("button");
let cancelCallBack = null;
btns[1].onclick = function() {
//实例对象没有 构造函数静态方法和属性
const instance = axios.create({
baseURL:"https://xxx.com",
timeout: 3000,
method:"POST"
})
instance({
url:"/list",
data:{
Id:"2"
},
cancelToken: new axios.CancelToken((c)=>{
cancelCallBack = c;
})
}).then(res => {
})
}
btns[2].onclick = function() {
cancelCallBack();
}
阅读axios源码学习到什么?
- axios对象创建:该对象既可以当对象使用,也可以当函数使用; 任何的发送请求都是有
request
方式执行
//Axios 构造函数
function Axios(config) {
this.defaults = config;
this.interceptors = {
request: {},
response: {}
}
}
Axios.prototype.request = function(config) {
console.log("发送ajax请求", config.method)
}
Axios.prototype.get = function(config) {
return this.request(config);
}
Axios.prototype.post = function(config) {
return this.request(config);
}
// 核心方法 生成axios对象: 当对象使用,也可以当方法使用
function createInstance(config) {
//实例化一个对象
let context = new Axios(config);// context.get() context.post(), 但是不能当作函数使用 context() X
//创建请求函数
let instance = Axios.prototype.request.bind(context);// 等价 context.request(), 但是不能当作对象使用 属性和方法
// 把Axios.prototype对象的方法添加到instance 函数对象中,但是没有构造函数中的属性 default interceptors
Object.keys(Axios.prototype).forEach(key => {
instance[key] = Axios.prototype[key].bind(context);
})
//给instance 添加 default interceptors
Object.keys(context).forEach(key => {
console.log(key)
instance[key] = context[key];
})
return instance;
}
let axios = createInstance({method:"post"})
axios({method:"post"}) //
axios.request({method:"post"})
axios发送请求过程
Document
//Axios 构造函数
function Axios(config) {
this.defaults = config;
this.interceptors = {
request: {},
response: {}
}
}
Axios.prototype.request = function(config) {
//发送请求
//1 创建promise对象,成功回调
let promise = Promise.resolve(config);
//2. 声明数组
let chains = [dispatchRequest, undefined];//undefined 占位
//调用 promise对象
let result = promise.then(chains[0], chains[1]);
// 返回 promise对象
return result;
}
// 1. 创建实例对象
function createInstance(config) {
//实例化一个对象
let context = new Axios(config);// context.get() context.post(), 但是不能当作函数使用 context() X
//创建请求函数
let instance = Axios.prototype.request.bind(context);// 等价 context.request(), 但是不能当作对象使用 属性和方法
// 把Axios.prototype对象的方法添加到instance 函数对象中,但是没有构造函数中的属性 default interceptors
Object.keys(Axios.prototype).forEach(key => {
instance[key] = Axios.prototype[key].bind(context);
})
//给instance 添加 default interceptors
Object.keys(context).forEach(key => {
console.log(key)
instance[key] = context[key];
})
return instance;
}
//2. dispatchRequest 函数; 处理分发 请求
function dispatchRequest(config) {
//调用适配器发送请求
return xhrAdapter(config).then(response => {
//对响应的结果处理,暂时不用处理
// ...
return response
}, error => {
throw error;
})
}
//3. adaper适配器; xhr发送请求
function xhrAdapter(config) {
return new Promise((resolve,reject) => {
//发送ajax请求 4步
let xhr = new XMLHttpRequest();
xhr.open(config.method, config.url);
xhr.setRequestHeader("Content-Type","application/json");
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status >= 200 && xhr.status {
console.log(res);
})
实现拦截器功能原理
通过这次手写拦截器功能,深入了解到,咋样给自己定义的对象添加自定义的遍历方法foreach,promise灵活运用,控制回调函数的执行顺序
-
axios原理图
axios拦截器实现原理.png -
模拟拦截器实现
//假设这是目标函数: 功能是发送请求的,因为异步所以用promise
function dispachRequest(config) {
return new Promise((resolve, reject) => {
setTimeout(() => {
//模拟成功状态和失败状态
// if (config.status == 200) {
// console.log("发送请求成功");
// resolve(config);
// } else {
// reject("放送请求失败")
// }
resolve(config);
}, 0);
})
}
//定义一个拦截器管理
//1. 存入回调函数
//2. 取出回调函数
function InterceptorManager() {
this.handlers = [];//存放不同拦截器的回调函数(成功和失败)
}
InterceptorManager.prototype.use = function (onResolved, onRejected) {
this.handlers.push({
onResolved,
onRejected
})
}
//给定义一个forEach方法:目的取出 handlers对应的回调函数
InterceptorManager.prototype.forEach = function (fn) {
myForEach(this.handlers, function(item) {
fn(item);
})
}
//自定义一个遍历方法
function myForEach(arr, fn) {
for(var i = 0; i {
console.dir("请求完成的数据"+ res)
},
err => {
console.log(err)
}
);
关键效果图

567.jpg

1616580117(1).png
- 将之前的 创建axios, 发送请求,拦截器,进行合并
总结不易,点波关注,万水千山总是情,点波关注行不行哟!!!