axios源碼分析--轉換請求數據和響應數據

axios支持轉換請求數據和響應數據ios

使用方式

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同樣使用方式git

源碼分析

axios源碼分析--請求流程傳送門,axios源碼分析--攔截器傳送門`github

axios(url, config),實際是調用Axios.prototype.request方法。Axios.prototype.request方法中鏈式調用chain至關於json

Promise.resolve(config)
.then(interceptors.request, interceptors.request)
...//多個請求攔截器
.then(dispatchRequest, undefined)
...//多個響應攔截器
.then(interceptors.response, interceptors.response)

複製代碼

其實dispatchRequest方法纔是真正的xhr請求,咱們進入axios/lib/core/dispatchRequest.js文件,看看它執行了什麼axios

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文件api

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方法bash

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覆蓋掉,若是想在默認上進行添加,能夠像以下定義方式app

transformResponse: axios.defaults.transformResponse.concat(function(){
    //todo
})
複製代碼

在請求配置config中data是post會傳遞的數據,params是拼接到url後的參數。默認的transformRequest方法,根據不一樣的data數據類型,對header和自身進行一些設置函數

相關文章
相關標籤/搜索