Aios

request config

{
  url: '/user',
  method: 'get', // default
  baseURL: '<https://some-domain.com/api>',

  // 'transformRequest' 允许在请求数据被发送到服务器之前对其进行更改
  // 这只适用于请求方法 'PUT'、'POST'、'PATCH' 和 'DELETE'
  // 必须 return 一个 string 或者 Buffer, ArrayBuffer, FormData or Stream 的实例
  // 你可以修改header对象
  transformRequest: [function (data, headers) {
    // 执行想要转换数据的任何操作
    return data;
  }],

  // 'transformResponse' 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    // 执行想要转换数据的任何操作
    return data;
  }],

  // 'headers' 是要发送的自定义头信息
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // 'params' 是与请求一起发送的URL参数
  // 必须是 普通对象 或 URLSearchParams 对象
  // 注意: 如果参数为 null 或 undefined ,则不会在 URL 中呈现
  params: {
    ID: 12345
  },

  // 'paramsSerializer' 是一个负责序列化 'params' 的可选函数
  paramsSerializer: function (params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },

  // 'data' 是作为请求体发送的数据
  // 仅适用于请求方法 'PUT'、'POST'、'DELETE' 和 'PATCH'
  // 当没有设置 'transformRequest' 时,必须是以下类型之一:
  // - string, 普通对象, ArrayBuffer, ArrayBufferView, URLSearchParams
  // - 浏览器只支持: FormData, File, Blob
  // - Node 只支持: Stream, Buffer
  data: {
    firstName: 'Fred'
  },
  // 'timeout' 指定请求超时前的毫秒数
  // 如果请求时间超过 'timeout',则请求将被中止
  timeout: 1000, // 默认值是 `0`

  // `withCredentials` 当前请求为跨域类型时是否在请求中协带cookie
  withCredentials: false, // 默认

  // `responseType` indicates the type of data that the server will respond with
  // options are: 'arraybuffer', 'document', 'json', 'text', 'stream'
  //   browser only: 'blob'
  responseType: 'json', // default

  // 'validateStatus' 定义是否 resolve 或 reject 给定 HTTP 响应状态码的 Promise
  // 如果此方法返回 `true` (或者设置成 `null/undefined`), 则 Promise 判定为 resolve;
  // 否则 Promise 会被 reject.
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 默认 200、300 间才走 then,否则 catch
  },

  // 'cancelToken' 用来取消 ajax 请求
  cancelToken: new CancelToken(function (cancel) {
  }),
}

get 请求

async getStudents() {
  const data = await axios({
    url: '<http://localhost:3000/students>',
    method: 'get',
    params: {
      id: 3
    },
  });
  console.log(data);
}

Untitled

打印 data 后我们会发现,真正的数据在 data 下的 data 中 :

Untitled

修改 Content-Type

通过常规三种方式设置 Content-Type 都无效:

// 全局:
axios.defaults.headers.get['Content-Type'] = 'application/x-www-form-urlencoded';
// 实例中:
async getStudents() {
  const data = await axios({
    url: '<http://localhost:3000/students>',
    method: 'get',
    params: {
      id: 3
    },
    headers: {
      'Content-Type': 'application/x-www-form-urlencoded'
    }
  });
  console.log(data);
}
// 拦截器中:
axios.interceptors.request.use((config) => {
  config.headers.get['Content-Type'] = 'application/x-www-form-urlencoded';
  return config;
})

最后在查看 axios 源码时发现在没有设置 requestData (也就是 config.data)并且设置 content-type 时,会把 content-type 删除:

// Add headers to the request
if ('setRequestHeader' in request) {
  utils.forEach(requestHeaders, function setRequestHeader(val, key) {
    if (typeof requestData === 'undefined' && key.toLowerCase() === 'content-type') {
      // Remove Content-Type if data is undefined
      delete requestHeaders[key];
    } else {
      // Otherwise add header to the request
      request.setRequestHeader(key, val);
    }
  });
}

这么做的原因在于是 get 请求本身是不需要 Content-Type的(get 请求在 不自定义headers 时是简单请求),但在知道源码的情况下,我们可以通过手动设置 data 来不走它此处的 if :

axios.interceptors.request.use((config) => {
  if (config.method === 'get') {
    config.data = true;
    config.headers.get['Content-Type'] = 'application/x-www-form-urlencoded';
  }

  console.log(config.headers);
  return config;
})