axios支持转换请求数据和响应数据
使用方式
transformRequest?: AxiosTransformer | AxiosTransformer[];
transformResponse?: AxiosTransformer | AxiosTransformer[];
axios('https://api.github.com/users/mzabriskie', {
transformResponse:[function (data, headers) {
//todo
return data;
}, function (data, headers) {
//todo
return data;
}],
transformResponse: [function (data, headers) {
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) { /* Ignore */ }
}
return data;
}],
}).then(()=>{
}).catch(()=>{
})
transformRequest和transformResponse一样使用方式
源码分析
axios源码分析--请求流程传送门,axios源码分析--拦截器传送门`
axios(url, config),实际是调用Axios.prototype.request方法。Axios.prototype.request方法中链式调用chain相当于
Promise.resolve(config)
.then(interceptors.request, interceptors.request)
...//多个请求拦截器
.then(dispatchRequest, undefined)
...//多个响应拦截器
.then(interceptors.response, interceptors.response)
其实dispatchRequest方法才是真正的xhr请求,我们进入axios/lib/core/dispatchRequest.js文件,看看它执行了什么
module.exports = function dispatchRequest(config) {
//...
//取消请求的判断
//转换请求数据
config.data = transformData(
config.data,
config.headers,
config.transformRequest
);
//...
var adapter = config.adapter || defaults.adapter;
return adapter(config).then(function onAdapterResolution(response) {
//...
//取消请求的判断
//转换响应数据
response.data = transformData(
response.data,
response.headers,
config.transformResponse
);
return response;
}, function onAdapterRejection(reason) {
if (!isCancel(reason)) {
//...
//取消请求的判断
if (reason && reason.response) {
// 转换响应数据
reason.response.data = transformData(
reason.response.data,
reason.response.headers,
config.transformResponse
);
}
}
return Promise.reject(reason);
});
};
调用transformData方法进行数据转换,进入到axios/lib/core/transformData.js文件
function transformData(data, headers, fns) {
utils.forEach(fns, function transform(fn) {
data = fn(data, headers);
});
return data;
};
其实就是将transformRequest或者transformResponse这样的函数数组,传递data和headers参数,在请求前和响应后对data数据和header数据进行一些定制化处理
defaults中定义有默认transformRequest和transformResponse方法
var defaults = {
//...
transformRequest: [function transformRequest(data, headers) {
normalizeHeaderName(headers, 'Accept');
normalizeHeaderName(headers, 'Content-Type');
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();
}
if (utils.isObject(data)) {
setContentTypeIfUnset(headers, 'application/json;charset=utf-8');
return JSON.stringify(data);
}
return data;
}],
transformResponse: [function transformResponse(data) {
if (typeof data === 'string') {
try {
data = JSON.parse(data);
} catch (e) { /* Ignore */ }
}
return data;
}],
//...
}
直接transformResponse:[],会把defaults.transformResponse覆盖掉,如果想在默认上进行添加,可以像如下定义方式
transformResponse: axios.defaults.transformResponse.concat(function(){
//todo
})
在请求配置config中data是post会传递的数据,params是拼接到url后的参数。默认的transformRequest方法,根据不同的data数据类型,对header和自身进行一些设置