1、源码
lib/core/dispatchRequest.js
1、transformRequest: 对 config 中的 data 进行加工,比如对 post 请求的 data 进行字符串化 (JSON.stringify(data))
2、adapter:适配器,包含浏览器端 xhr 和 node 端的 http
3、transformResponse: 对服务端响应的数据进行加工,比如 JSON.parse(data)
let transformData = require('./transformData')
var defaults = require('../../defaults');
module.exports = function dispatchRequest(config) {
// 转换数据类型
// transformRequest 方法,上下文绑定 config,对 data 和 headers 进行加工
config.data = transformData.call(
config, // 上下文环境,即 this 指向
config.data,
config.headers,
config.transformRequest // 转换请求的数据, 在defaults中
);
// ...
// 适配器,可自定义,没有的用默认的
const adapter = config.adapter || defaults.adapter
// 通过适配器处理 config 配置,返回服务端响应数据 response
return adapter(config).then(function onAdapterResolution(response) {
// ...
// 转换数据
response.data = transformData.call(
config,
response.data,
response.headers,
config.transformResponse // 转换返回的数据,如json
);
//...
return response
}, function onAdapterRejection(reason) {
//...
return Promise.reject(reason)
})
}
lib/core/transformData.js 转换数据
module.exports = function transformData (data, headers, fns) {
// fns:一个数组,包含一个或多个方法转换器方法
utils.forEach(fns, function transform(fn) {
// 绑定上下文 context,传入 data 和 headers 参数进行加工
data = fn(data, headers)
})
return data
}
defaults.js
import utils from './utils'
var defaults = {
// ...
// 请求超时时间,默认不超时
timeout: 0,
// 转换请求
transformRequest: [function transformRequest(data, headers) {
// 判断 data
if (utils.isFormData(data) ||
utils.isArrayBuffer(data) ||
utils.isBuffer(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();
}
// 如果 data 是对象,或 Content-Type 设置为 application/json
if (utils.isObject(data) || (headers && headers['Content-Type'] === 'application/json')) {
// 设置 Content-Type 为 application/json
setContentTypeIfUnset(headers, 'application/json');
// 将 data 转换为 json 字符串返回
return JSON.stringify(data);
}
return data;
}],
// 转换响应数据
transformResponse: [function transformResponse(data) {
// ...
if (typeof data === 'string') {
try {
// 将 data 转换为 json 对象并返回
return JSON.parse(data);
} catch (e) {
// ...
}
}
return data;
}],
// ...判断响应状态码的合法性: [200, 299]
// ...默认的适配器
}
2、扩展: 重写 / 新增转换方法
发现transformRequest方法是default对象上的一个属性,那我们可以通过自定义配置来改写转换的过程
import axios from 'axios';
// 重写转换请求数据的过程
axios.default.transformRequest = [(data, headers) => {
//...
return data
}];
// 增加对请求数据的处理
axios.default.transformRequest.push((data, headers) => {
// ...
return data
});