Axios源码阅读笔记#1 默认配置项

摘要:
后来仔细想了一下,Axios是用Ajax实现异步请求的,而异步操作则是基于Promise的。而Axios的目的呢,就是为了在浏览器和node.js中,以统一、简洁的方式使用Ajax、处理回调。最简单的使用方法,仅仅需要向Axios传递请求地址,便可以发送一个GET请求。Ajax中其它的配置Axios都已经默认设置好了。当然也可以根据需求传入config,覆盖默认配置项。Axios基于Promise就体现在adapter。XHR在浏览器中Axios使用的是XMLHttpRequest。我们通常会将Ajax等同于XMLHttpRequest,但两者并不一样。
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: functionvalidateStatus(status) {
    return status >= 200 && status < 300;
  }
};
defaults.headers ={
  common: {
    'Accept': 'application/json, text/plain, */*'
  }
};
utils.forEach(['delete', 'get', 'head'], functionforEachMehtodNoData(method) {
  defaults.headers[method] ={};
});
utils.forEach(['post', 'put', 'patch'], functionforEachMethodWithData(method) {
  defaults.headers[method] =utils.merge(DEFAULT_CONTENT_TYPE);
});
module.exports = defaults;

adapter

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

functiongetDefaultAdapter() {
  varadapter;
  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');
  }
  returnadapter;
}

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: [functiontransformRequest(data, headers) {
    normalizeHeaderName(headers, 'Content-Type');
    if (utils.isFormData(data) ||
      utils.isArrayBuffer(data) ||
      utils.isStream(data) ||
      utils.isFile(data) ||
      utils.isBlob(data)
    ) {
      returndata;
    }
    if(utils.isArrayBufferView(data)) {
      returndata.buffer;
    }
    if(utils.isURLSearchParams(data)) {
      setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8');
      returndata.toString();
    }
    if(utils.isObject(data)) {
      setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
      returnJSON.stringify(data);
    }
    returndata;
  }],
transformResponse
transformResponse 默认将响应数据转换为 JSON格式。
transformResponse: [functiontransformResponse(data) {
    /*eslint no-param-reassign:0*/
    if (typeof data === 'string') {
// var PROTECTION_PREFIX = /^)]}',? /; data
= data.replace(PROTECTION_PREFIX, ''); try{ data =JSON.parse(data); } catch (e) { /*Ignore */} } returndata; }],
了解 Axios 的默认配置项之后,就明白如何通过 config 来自定义请求了。

免责声明:文章转载自《Axios源码阅读笔记#1 默认配置项》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇让pandas的输出结果中显示全部数据linux命令--mv下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

curl使用

curl -H "Content-Type:application/json" -X POST --data '{"name":"zhangsan"}' http://127.0.0.1:9000/helloWorld curl命令用法: curl [options...] <url> 常用参数有: --connect-timeout <...

基于canal的client-adapter数据同步必读指南

本文将介绍canal项目中client-adapter的使用,以及落地生产中需要考虑的可靠性、高可用与监控报警。(基于canal 1.1.4版本)   canal作为mysql的实时数据订阅组件,实现了对mysql binlog数据的抓取。 虽然阿里也开源了一个纯粹从mysql同步数据到mysql的项目otter(github.com/alibaba/ot...

2-开发共享版APP(接入指南)-设备接入说明:快速接入

https://www.cnblogs.com/yangfengwu/p/11249674.html 该APP安装包下载链接: http://www.mnif.cn/appapk/IotDevelopmentVersion/20190820/app-debug.apk 或者扫描二维码下载 APP源码获取方式:(请阅读宝贝说明) 此APP建立在基础篇,升...

mongo分页查询,同时返回分页记录和记录数

今天做了一个mongo的分页查询,记录一下mongo如何同时返回分页记录和记录数的方法,利用的是mongo的聚合查询里面的$facet阶段,具体使用参考官方文档即可https://docs.mongodb.com/manual/reference/operator/aggregation/facet/ 按照官方文档的说法, Input documents...

分离Webpack开发环境与生产环境的配置

这是Webpack+React系列配置过程记录的第五篇。其他内容请参考: 第一篇:使用webpack、babel、react、antdesign配置单页面应用开发环境 第二篇:使用react-router实现单页面应用路由 第三篇:优化单页面开发环境:webpack与react的运行时打包与热更新 第四篇:React配合Webpack实现代码分割与异步加...

snmp配置

思科路由器打开方法: snmp-server community crmRO //crm为自定义的共同体名称,常用Publicsnmp-server trap-sourceFastEthernet0/3/0 //监控的端口snmp-server host x.x.x.xcrm //在哪台终端(公网地址x.x.x.x)上应用共同体snmp-server en...