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 中。

  1. axios(url[, config])

default

  1. var defaults = {
  2. adapter: getDefaultAdapter(),
  3.  
  4. transformRequest: [...],
  5.  
  6. transformResponse: [...],
  7.  
  8. timeout: 0, // 请求超时时间
  9.  
  10. xsrfCookieName: 'XSRF-TOKEN', // 用于获取 cookie 中 'XSRF-TOKEN' 的值
  11. xsrfHeaderName: 'X-XSRF-TOKEN', // 用于设置请求头部
  12.  
  13. maxContentLength: -1,
  14.  
  15. validateStatus: function validateStatus(status) {
  16. return status >= 200 && status < 300;
  17. }
  18. };
  19.  
  20. defaults.headers = {
  21. common: {
  22. 'Accept': 'application/json, text/plain, */*'
  23. }
  24. };
  25.  
  26. utils.forEach(['delete', 'get', 'head'], function forEachMehtodNoData(method) {
  27. defaults.headers[method] = {};
  28. });
  29.  
  30. utils.forEach(['post', 'put', 'patch'], function forEachMethodWithData(method) {
  31. defaults.headers[method] = utils.merge(DEFAULT_CONTENT_TYPE);
  32. });
  33.  
  34. module.exports = defaults;

adapter

浏览器和 node.js 实现异步请求的方式并不一样,那么 Axios 如何实现统一呢?

  1. function getDefaultAdapter() {
  2. var adapter;
  3. if (typeof XMLHttpRequest !== 'undefined') {
  4. // For browsers use XHR adapter
  5. adapter = require('./adapters/xhr');
  6. } else if (typeof process !== 'undefined') {
  7. // For node use HTTP adapter
  8. adapter = require('./adapters/http');
  9. }
  10. return adapter;
  11. }

var defaults = {
  adapter: getDefaultAdapter(),

  ...

}

  1.  

module.exports = defaults;

  1.  

在 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’字段。

  1. // Add xsrf header
  2. // This is only done if running in a standard browser environment.
  3. // Specifically not if we're in a web worker, or react-native.
  4. if (utils.isStandardBrowserEnv()) {
  5. var cookies = require('./../helpers/cookies');
  6.  
  7. // Add xsrf header
  8. var xsrfValue = (config.withCredentials || isURLSameOrigin(config.url)) && config.xsrfCookieName ?
  9. cookies.read(config.xsrfCookieName) :
  10. undefined;
  11.  
  12. if (xsrfValue) {
         // 默认配置中 xsrfHeadeName: 'X-XSRF-TOKEN'
  13. requestHeaders[config.xsrfHeaderName] = xsrfValue;
  14. }
  15. }

transformRequest

  1. transformRequest 是根据请求数据的类型对数据进行转换,并改变 Content-Type。默认的  Content-Type application/x-www-form-urlencoded
  1. transformRequest: [function transformRequest(data, headers) {
  2. normalizeHeaderName(headers, 'Content-Type');
  3. if (utils.isFormData(data) ||
  4. utils.isArrayBuffer(data) ||
  5. utils.isStream(data) ||
  6. utils.isFile(data) ||
  7. utils.isBlob(data)
  8. ) {
  9. return data;
  10. }
  11. if (utils.isArrayBufferView(data)) {
  12. return data.buffer;
  13. }
  14. if (utils.isURLSearchParams(data)) {
  15. setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
  16. return data.toString();
  17. }
  18. if (utils.isObject(data)) {
  19. setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
  20. return JSON.stringify(data);
  21. }
  22. return data;
  23. }],
  1. transformResponse
  1. transformResponse 默认将响应数据转换为 JSON格式。
  1. transformResponse: [function transformResponse(data) {
  2. /*eslint no-param-reassign:0*/
  3. if (typeof data === 'string') {
        // var PROTECTION_PREFIX = /^\)\]\}',?\n/;
  4. data = data.replace(PROTECTION_PREFIX, '');
  5. try {
  6. data = JSON.parse(data);
  7. } catch (e) { /* Ignore */ }
  8. }
  9. return data;
  10. }],
  1. 了解 Axios 的默认配置项之后,就明白如何通过 config 来自定义请求了。

Axios源码阅读笔记#1 默认配置项的更多相关文章

  1. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是“引导”文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http://you.host.c ...

  2. Apollo源码阅读笔记(二)

    Apollo源码阅读笔记(二) 前面 分析了apollo配置设置到Spring的environment的过程,此文继续PropertySourcesProcessor.postProcessBeanF ...

  3. 源码阅读笔记 - 1 MSVC2015中的std::sort

    大约寒假开始的时候我就已经把std::sort的源码阅读完毕并理解其中的做法了,到了寒假结尾,姑且把它写出来 这是我的第一篇源码阅读笔记,以后会发更多的,包括算法和库实现,源码会按照我自己的代码风格格 ...

  4. Three.js源码阅读笔记-5

    Core::Ray 该类用来表示空间中的“射线”,主要用来进行碰撞检测. THREE.Ray = function ( origin, direction ) { this.origin = ( or ...

  5. jdk源码阅读笔记-LinkedHashMap

    Map是Java collection framework 中重要的组成部分,特别是HashMap是在我们在日常的开发的过程中使用的最多的一个集合.但是遗憾的是,存放在HashMap中元素都是无序的, ...

  6. gogs 源码阅读笔记 001

    gogs 源码阅读笔记 001 gogs项目相当不错,本笔记实际是基于gogs fork版本 git-122a66f. gitea (gitea版本由来)[https://blog.gitea.io/ ...

  7. Apollo源码阅读笔记(一)

    Apollo源码阅读笔记(一) 先来一张官方客户端设计图,方便我们了解客户端的整体思路. 我们在使用Apollo的时候,需要标记@EnableApolloConfig来告诉程序开启apollo配置,所 ...

  8. HashMap源码阅读笔记

    HashMap源码阅读笔记 本文在此博客的内容上进行了部分修改,旨在加深笔者对HashMap的理解,暂不讨论红黑树相关逻辑 概述   HashMap作为经常使用到的类,大多时候都是只知道大概原理,比如 ...

  9. guavacache源码阅读笔记

    guavacache源码阅读笔记 官方文档: https://github.com/google/guava/wiki/CachesExplained 中文版: https://www.jianshu ...

随机推荐

  1. 2017-4-25/设计缓存(LFU)

    1. 恒定缓存性能有哪些因素? 命中率.缓存更新策略.缓存最大数据量. 命中率:指请求缓存次数和缓存返回正确结果次数的比例.比例越高,缓存的使用率越高,用来衡量缓存机智的好坏和效率.如果数据频繁更新, ...

  2. HTML特殊符号对照表 常用字符实体

    前沿:阿飞表示虽然大部分都不常用,但是有些基本的还是要背下的,比如空格,大于,小于.^_^

  3. 学问Chat UI(3)

    前言 上文学问Chat UI(2)分析了消息适配器的实现; 本文主要学习下插件功能如何实现的.并以图片插件功能作为例子详细说明,分析从具体代码入手; 概要 分析策略说明 "+"功能 ...

  4. Android 音视频开发(二):使用 AudioRecord 采集音频数据并保存到文件

    版权声明:转载请说明出处:http://www.cnblogs.com/renhui/p/7457321.html 一.AudioRecord API详解 AudioRecord是Android系统提 ...

  5. 入侵拿下DVBBS php官网详细过程(图)

    几 个月前,DVBBS php2.0暴了一个可以直接读出管理员密码的sql注入漏洞,当时这个漏洞出来的时候,我看的心痒,怎么还会有这么弱智的漏洞,DVBBS php2.0这套代码我还没仔细看过,于是5 ...

  6. Animate.css 一款牛逼的css3动画库

    Animate.css是一款很牛逼的,跨浏览器的css3动画库,使用方法也很简单只要引入一个animate.min.css就可以了, 简单使用 1 首先引入 animate的 css 文件样式 cdn ...

  7. C# 爬虫 Jumony html解析

    前言 前几天写了个爬虫,然后认识到了自己的不足.感谢 "倚天照海- -" ,我通过你推荐的文章,意外的发现了html解析的类库——Jumony. 研究了2天,我发现这个东西简单粗暴 ...

  8. P问题、NP问题、NPC问题

    看师兄们的论文经常说一句这是个NP难问题,所以采用另外一种方法来代替(比如凸松弛,把l0范数的问题松弛为l1范数的问题来求解).然后搜索了相关知识,也还是没看太懂,把一些理论知识先贴上来,希望以后再接 ...

  9. 理解 angular 的路由功能

    相信很多人使用angular 都是因为他路由功能而用的 深入理解ANGULARUI路由_UI-ROUTER 最近在用 ionic写个webapp 看到几个demo中路由有好几种,搞的有点晕,查下资料研 ...

  10. chrome开发工具指南(二)

    Application 面板 使用 App Manifest 窗格检查您的网络应用清单和触发 Add to Homescreen 事件. 使用 Service Worker 窗格执行与服务工作线程相关 ...