内容简介:如果大家有了解过
源码架构
- 创建一个
Axios构造函数,添加默认配置,拦截器,原型上挂载请求方法
// core/axios.js
// 构造Axios构造函数
function Axios(instanceConfig) {
this.defaults = instanceConfig;
// 添加拦截器
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
// 实际请求方法
Axios.prototype.request = function() {};
Axios.prototype.getUri = function() {};
// 没有请求体 delete get head options
Axios.prototype.get = function(url, config = {}) {
return this.request(Object.assign(config, {
method: 'get',
url
}))
};
// 有请求体 post put patch
Axios.prototype.post = function(url, data, config = {}) {
return this.request(Object.assign(config, {
method: 'post',
url,
data
}))
};
复制代码
- 实例化一个
Axios实例context,接着创建instance指向Axios.prototype.request方法,并绑定了上下文context; - 通过
extend方法把context中的原型方法和实例方法全部拷贝到instance上 ,返回instance - 创建一个默认实例,挂载快捷方法
create,CancelToken,all等方法
// axios.js
// 创建一个Axios实例,挂载辅助方法,并导出该混合对象
function createInstance(defaultConfig = {}) {
var context = new Axios(defaultConfig);
var instance = bind(Axios.prototype.request, context);
// Copy axios.prototype to instance
utils.extend(instance, Axios.prototype, context)
// copy context to instance
utils.extend(instance, context)
return intance
}
// create the default instance to be exported
var axios = createInstance({})
axios.Axios = Axios
axios.create= function(config) {
return createInstance(Object.assign(axios.defaults, config))
}
// 取消请求
axios.Cancel = require('./cancel/Cancel')
axios.CancelToken = require('./cancel/CancelToken')
axios.isCancel = require('./cancel/isCancel')
// Prmoise.all 的语法糖
axios.all = Promise.all
axios.spread = require('./helpers/spread')
复制代码
如何实现 axios 所支持的的功能
支持 Node 和 浏览器 端的 http 请求
-
关键代码
-
原理介绍
- 通过
process区分出Node环境和浏览器环境 - 浏览器环境使用
XMLHttpRquest发起http请求,Node环境使用http,https模块发起请求 - 通过
Promise包装实现请求方法
- 通过
请求响应拦截器
-
关键代码
- lib/core/InterceptorManager.js
- lib/core/Axio.js
-
拦截器运行示意
Promise .then(request[1].fulfilled, request[1].rejected) .then(request[0].fulfilled, request[1].rejected) .then(dispatchRequest, undefined) .then(response[0].fulfilled, response[0].rejected) .then(response[1].fulfilled, response[1].rejected) .then() // user opt 复制代码
- 原理介绍
- 实现一个拦截器类中维护一个数组,添加拦截器方法
use, 移除拦截器方法eject, 遍历拦截器方法forEach - 利用数组
unshift,push方法,添加请求拦截器和响应拦截器 - 利用
Promise.then链式调用添加的拦截器
- 实现一个拦截器类中维护一个数组,添加拦截器方法
如果大家有了解过 Koa 的中间件原理,可能会发现很相似
转换请求和响应数据
-
关键代码
-
原理介绍
- 默认配置中内置默认
transformRequest,transformResponse方法,处理常见情况 - 编写
transformData方法,遍历多个转换器,处理数据
- 默认配置中内置默认
function transformData(data, headers, fns) {
/*eslint no-param-reassign:0*/
utils.forEach(fns, function transform(fn) {
data = fn(data, headers);
});
return data;
};
复制代码
-
dispatchRequest请求前,调用transformData调用所有的请求转化器处理请求数据 - 请求完成后,调用
transformData调用所有的响应转化器处理响应数据
取消请求
-
关键代码
-
原理介绍
- 创建一个
CancelToken构造函数接受一个executor函数,内部实例化一个pending状态的Promise对象,然后用一个resolvePromise变量指向resolve函数。 - 接着执行 executor 函数,传入一个
cancel函数,在cancel函数内部,会调用resolvePromise把Promise对象从pending状态变为resolved状态。 - 在
request请求中的resolvePromise.then被执行
- 创建一个
客户端支持防范 XSRF
- XSRF介绍
-
防范方法
- 验证请求
referer, 但由于referer也可以伪造,作用有限 - 服务器端生成
token,并通过set-cookie的方式种到客户端,然后客户端发送请求的时候,从cookie中对应的字段读取出token,然后添加到请求headers中。由于这个token比较难伪造,所以就能区分这个请求是否是用户正常发起的。
- 验证请求
-
关键代码
-
原理介绍
- 首先判断如果是配置
withCredentials为true或者是同域请求,我们才会请求headers添加xsrf相关的字段。 - 如果判断成功,尝试从
cookie中读取xsrf的token值。 - 如果能读到,则把它添加到请求
headers的xsrf相关字段中。
- 首先判断如果是配置
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
UML基础与Rose建模案例
吴建 / 人民邮电出版社 / 2004-10 / 29.00元
《UML 基础与Rose建模案例》介绍了用UML(统一建模语言)进行软件建模的基础知识以及Rational Rose工具的使用方法,其中,前8章是基础部分,对软件工程思想、UML的相关概念、Rational Rose工具以及RUP软件过程等进行了详细的介绍;后3章是案例部分,通过3个综合实例,对UML建模(以Rose为实现工具)的全过程进行了剖析;最后的附录中给出了UML中常用的术语、标准元素和元......一起来看看 《UML基础与Rose建模案例》 这本书的介绍吧!