Axios源码阅读笔记#1 默认配置项
Promise based HTTP client for the browser and node.js
这是 Axios 的定义,Axios 是基于 Promise,用于HTTP客户端——浏览器和 node.js 的库 。Github:https://github.com/mzabriskie/axios。
官方文档中 Axios 的 feature 有:
1)浏览器中使用 XMLHttpRequest;
2)node.js 中使用 http 请求;
3)支持 Promise API;
4)能够拦截请求与响应;
5)能够转换请求与响应的数据;
6)请求能够取消;
7)自动转换 JSON 数据;
8)客户端支持防范 XSRF;
记得有一次面试中,面试官问到,Axios 是用什么实现的,我回答说 Ajax。看面试官的表情,他似乎认为这个答案是错的。后来仔细想了一下,Axios 是用 Ajax 实现异步请求的, 而异步操作则是基于 Promise 的。而 Axios 的目的呢,就是为了在浏览器和 node.js 中,以统一、简洁的方式使用 Ajax、处理回调。简单的说,就是用 Promise 包装了一下 AJAX(当然并没有这么简单)。
最简单的使用方法,仅仅需要向 Axios 传递请求地址,便可以发送一个 GET 请求。Ajax 中其它的配置 Axios 都已经默认设置好了。当然也可以根据需求传入 config,覆盖默认配置项。默认配置定义在 /lib/defaults.js 中。
axios(url[, config])
default
var defaults = {
adapter: getDefaultAdapter(),
transformRequest: [...],
transformResponse: [...],
timeout: 0, // 请求超时时间
xsrfCookieName: 'XSRF-TOKEN', // 用于获取 cookie 中 'XSRF-TOKEN' 的值
xsrfHeaderName: 'X-XSRF-TOKEN', // 用于设置请求头部
maxContentLength: -1,
validateStatus: function validateStatus(status) {
return status >= 200 && status < 300;
}
};
defaults.headers = {
common: {
'Accept': 'application/json, text/plain, */*'
}
};
utils.forEach(['delete', 'get', 'head'], function forEachMehtodNoData(method) {
defaults.headers[method] = {};
});
utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
});
module.exports = defaults;
adapter
浏览器和 node.js 实现异步请求的方式并不一样,那么 Axios 如何实现统一呢?
function getDefaultAdapter() {
var adapter;
if (typeof XMLHttpRequest !== 'undefined') {
// For browsers use XHR adapter
adapter = require('./adapters/xhr');
} else if (typeof process !== 'undefined') {
// For node use HTTP adapter
adapter = require('./adapters/http');
}
return adapter;
}
var defaults = {
adapter: getDefaultAdapter(),
...
}
module.exports = defaults;
在 defaults.js 中,通过分支选择判断,若 XMLHttpRequest 存在,代表当前环境为浏览器, 则异步请求将使用 XHR;否则,若存在 process,代表当前环境为 node.js,则使用 HTTP。
Axios 基于 Promise 就体现在 adapter。无论是 XHR 还是 HTTP,都是经过 Promise 包装的,getDefaultAdapter() 返回的都是一个 Promise 对象。如果希望使用 fetch 或者其他自定义,在 config 中传入 adapter 就可以了,参考 gthub 的 /lib/adapters/README.md 的示例, adapter 应该是一个 Promise 对象。
XHR
在浏览器中 Axios 使用的是 XMLHttpRequest。我们通常会将 Ajax 等同于 XMLHttpRequest,但两者并不一样。《JavaScript 高级程序设计》中提到,“Ajax 技术的核心是 XMLHttpRequest 对象(简称XHR)”。在 xhr.js 中,主要是对 XHR请求以及响应数据的一些封装,使它能够兼容 IE8/9。
上文提到客户端支持 XSRF防范 ,是在 xhr.js 中实现。往请求头中插入‘X-XSRF-TOKEN’字段。
// Add xsrf header
// This is only done if running in a standard browser environment.
// Specifically not if we're in a web worker, or react-native.
if (utils.isStandardBrowserEnv()) {
var cookies = require('./../helpers/cookies'); // Add xsrf header
var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
cookies.read(config.xsrfCookieName) :
undefined; if (xsrfValue) {
// 默认配置中 xsrfHeadeName: 'X-XSRF-TOKEN'
requestHeaders[config.xsrfHeaderName] = xsrfValue;
}
}
transformRequest
transformRequest 是根据请求数据的类型对数据进行转换,并改变 Content-Type。默认的 Content-Type 为 ‘application/x-www-form-urlencoded’
transformRequest: [function transformRequest(data, headers) {
normalizeHeaderName(headers, 'Content-Type');
if (utils.isFormData(data) ||
utils.isArrayBuffer(data) ||
utils.isStream(data) ||
utils.isFile(data) ||
utils.isBlob(data)
) {
return data;
}
if (utils.isArrayBufferView(data)) {
return data.buffer;
}
if (utils.isURLSearchParams(data)) {
setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
return data.toString();
}
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
return data;
}],
transformResponse
transformResponse 默认将响应数据转换为 JSON格式。
transformResponse: [function transformResponse(data) {
/*eslint no-param-reassign:0*/
if (typeof data === 'string') {
// var PROTECTION_PREFIX = /^\)\]\}',?\n/;
data = data.replace(PROTECTION_PREFIX, '');
try {
data = JSON.parse(data);
} catch (e) { /* Ignore */ }
}
return data;
}],
了解 Axios 的默认配置项之后,就明白如何通过 config 来自定义请求了。
Axios源码阅读笔记#1 默认配置项的更多相关文章
- CI框架源码阅读笔记4 引导文件CodeIgniter.php
到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...
- Apollo源码阅读笔记(二)
Apollo源码阅读笔记(二) 前面 分析了apollo配置设置到Spring的environment的过程,此文继续PropertySourcesProcessor.postProcessBeanF ...
- 源码阅读笔记 - 1 MSVC2015中的std::sort
大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...
- Three.js源码阅读笔记-5
Core::Ray 该类用来表示空间中的“射线”,主要用来进行碰撞检测. THREE.Ray = function ( origin, direction ) { this.origin = ( or ...
- jdk源码阅读笔记-LinkedHashMap
Map是Java collection framework 中重要的组成部分,特别是HashMap是在我们在日常的开发的过程中使用的最多的一个集合.但是遗憾的是,存放在HashMap中元素都是无序的, ...
- gogs 源码阅读笔记 001
gogs 源码阅读笔记 001 gogs项目相当不错,本笔记实际是基于gogs fork版本 git-122a66f. gitea (gitea版本由来)[https://blog.gitea.io/ ...
- Apollo源码阅读笔记(一)
Apollo源码阅读笔记(一) 先来一张官方客户端设计图,方便我们了解客户端的整体思路. 我们在使用Apollo的时候,需要标记@EnableApolloConfig来告诉程序开启apollo配置,所 ...
- HashMap源码阅读笔记
HashMap源码阅读笔记 本文在此博客的内容上进行了部分修改,旨在加深笔者对HashMap的理解,暂不讨论红黑树相关逻辑 概述 HashMap作为经常使用到的类,大多时候都是只知道大概原理,比如 ...
- guavacache源码阅读笔记
guavacache源码阅读笔记 官方文档: https://github.com/google/guava/wiki/CachesExplained 中文版: https://www.jianshu ...
随机推荐
- Struts2学习笔记(十)——自定义拦截器
Struts2拦截器是基于AOP思想实现的,而AOP的实现是基于动态代理.Struts2拦截器会在访问某个Action之前或者之后进行拦截,并且Struts2拦截器是可插拔的:Struts2拦截器栈就 ...
- c语言 内存管理
动态内存是由程序员手动分配,不再使用时,一定记得释放内存. 静态内存是程序开始运行时由编译器分配的内存,它的分配是程序开始编译时完成的,不占用cpu资源.程序中的各种变量在编译源程序时就已经分配了内存 ...
- C/C++ 对优先级与结合性的理解
优先级与结合性是指运算符与操作数的"紧密程度": 结合性表明了同一优先级的运算符对同一操作数的紧密程度: 如: a=b=c: 赋值运算符的结合性为从右至左: 所以a=b=c ...
- Win10各版本区别
Win10各版本之间的区别.. ------------------- =============================================功能最强大的,不是日后绝大多数中国用户 ...
- 微信H5支付:网络环境未能通过安全验证,请稍后再试。解决办法(PHP版)
前(tu)言(cao) (这段前言纯属吐槽,着急解决问题的小伙伴,赶紧看正文吧) 最近做了支付宝和微信支付,先做的是PC端网站的支付,就是出个二维码,然后手机扫描支付,当然支付宝在扫码页面支持登录支付 ...
- HTML5新结构标签和移动端页面布局
--------------------HTML5新结构标签--------------------1.h5新增的主要语义化标签如下: 1.header 页面头部.页眉 2.nav 页面导航 3.ar ...
- Spring Aop 应用实例与设计浅析
0.代码概述 代码说明:第一章中的代码为了突出模块化拆分的必要性,所以db采用了真实操作.下面代码中dao层使用了打印日志模拟插入db的方法,方便所有人运行demo. 1.项目代码地址:https:/ ...
- Linux_window与linux之间文件互传,上传下载
window与linux之间文件互传 运行环境:Centos os7 + win8.1 +putty putty:是一个Telnet,ssh,rlogin,纯tcp以及串行接口连接软件,由于linux ...
- Http get方式url参数长度以及大小
详见: http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp69 众所周知, 传递小量参数(在没有其他原因,例如隐藏参数值的情况下)推 ...
- java-多个数的和
目的:实现多个整数相加. 思路:1.首先要确定用户所需整数的个数n,此部分由用户在键盘上输入. 2.创建一个长度为n的数组. 3.用户从键盘上输入n个整数并判断是否输入正确,正确则存入数组,否则重新输 ...