axios使用及配置明细小记

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

1. Features

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

2. 安装

使用 npm:

$ npm install axios

使用 cdn:

3. API

首先从npm导入的axios包中(node_modules/axios/)找到入口文件index.d.ts,其中定义了axios的最外层交互API,主要内容罗列如下:


// 请求配置接口定义
export interface AxiosRequestConfig {
  url?: string;
  method?: string;
  baseURL?: string;
  transformRequest?: AxiosTransformer | AxiosTransformer[];
  transformResponse?: AxiosTransformer | AxiosTransformer[];
  headers?: any;
  params?: any;
  paramsSerializer?: (params: any) => string;
  data?: any;
  timeout?: number;
  withCredentials?: boolean;
  adapter?: AxiosAdapter;
  auth?: AxiosBasicCredentials;
  responseType?: string;
  xsrfCookieName?: string;
  xsrfHeaderName?: string;
  onUploadProgress?: (progressEvent: any) => void;
  onDownloadProgress?: (progressEvent: any) => void;
  maxContentLength?: number;
  validateStatus?: (status: number) => boolean;
  maxRedirects?: number;
  httpAgent?: any;
  httpsAgent?: any;
  proxy?: AxiosProxyConfig | false;
  cancelToken?: CancelToken;
}

// 响应结构接口定义
export interface AxiosResponse  {
  data: T;
  status: number;
  statusText: string;
  headers: any;
  config: AxiosRequestConfig;
  request?: any;
}

/**
 * 以下请求方法
 * axios(config: AxiosRequestConfig )
 * axios(url: string, config: AxiosRequestConfig)
 * axios.get(url: string, config: AxiosRequestConfig)
 * axios.post(url: string, data: any, config: AxiosRequestConfig)
 * 
 * 都返回AxiosPromise类型,便于用Promise的回调函数then/catch做相应的结果处理
 * 
 */
export interface AxiosPromise extends Promise> {
}

// axios 实例接口定义
export interface AxiosInstance {
  // 带有AxiosRequestConfig的构造函数
  (config: AxiosRequestConfig): AxiosPromise;
  // 带有url和AxiosRequestConfig的构造函数
  (url: string, config?: AxiosRequestConfig): AxiosPromise;
  // 给axios实例设置默认AxiosRequestConfig配置的属性
  defaults: AxiosRequestConfig;
  // 给axios实例设置interceptors的属性
  interceptors: {
    request: AxiosInterceptorManager;
    response: AxiosInterceptorManager;
  };
  request(config: AxiosRequestConfig): AxiosPromise;
  get(url: string, config?: AxiosRequestConfig): AxiosPromise;
  delete(url: string, config?: AxiosRequestConfig): AxiosPromise;
  head(url: string, config?: AxiosRequestConfig): AxiosPromise;
  post(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise;
  put(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise;
  patch(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise;
}
// 理解为axios实例的工厂对象,包含一些直接生成axios实例的方法,以及一些其他工具方法
export interface AxiosStatic extends AxiosInstance {
  create(config?: AxiosRequestConfig): AxiosInstance;
  Cancel: CancelStatic;
  CancelToken: CancelTokenStatic;
  isCancel(value: any): boolean;
  all(values: (T | Promise)[]): Promise;
  spread(callback: (...args: T[]) => R): (array: T[]) => R;
}

// 定义一个类型为AxiosStatic的实例变量Axios
declare const Axios: AxiosStatic;

// 作为默认对象导出Axios, 本质是导出了一个默认axios实例
export default Axios;

请求配置对象常用配置项说明:

{
  // `url` 是用于请求的服务器 URL
  url: '/user',

  // `method` 是创建请求时使用的方法
  method: 'get', // 默认是 get

  // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
  // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
  baseURL: 'https://some-domain.com/api/',

  // `transformRequest` 允许在向服务器发送前,修改请求数据
  // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
  transformRequest: [function (data) {
    // 对 data 进行任意转换处理

    return data;
  }],

  // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
  transformResponse: [function (data) {
    // 对 data 进行任意转换处理

    return data;
  }],

  // `headers` 是即将被发送的自定义请求头
  headers: {'X-Requested-With': 'XMLHttpRequest'},

  // `params` 是即将与请求一起发送的 URL 参数
  // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
  params: {
    ID: 12345
  },

  // `paramsSerializer` 是一个负责 `params` 序列化的函数
  // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
  paramsSerializer: function(params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
  },

  // `data` 是作为请求主体被发送的数据
  // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
  data: {
    firstName: 'Fred'
  },

  // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
  // 如果请求话费了超过 `timeout` 的时间,请求将被中断
  timeout: 1000,

  // `withCredentials` 表示跨域请求时是否需要使用凭证
  withCredentials: false, // 默认的


  // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
  responseType: 'json', // 默认的

  // `maxContentLength` 定义允许的响应内容的最大尺寸
  maxContentLength: 2000,

  // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject  promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
  validateStatus: function (status) {
    return status >= 200 && status < 300; // 默认的
  },
}

响应结构说明:

{
  // `data` 由服务器提供的响应
  data: {},

  // `status` 来自服务器响应的 HTTP 状态码
  status: 200,

  // `statusText` 来自服务器响应的 HTTP 状态信息
  statusText: 'OK',

  // `headers` 服务器响应的头
  headers: {},

  // `config` 是为请求提供的配置信息
  config: {}
}

使用 then 时,你将接收下面这样的响应:

axios.get('/user/12345')
  .then(response => {
    console.log(response.data);
    console.log(response.status);
    console.log(response.statusText);
    console.log(response.headers);
    console.log(response.config);
  })
  .catch(err => { console.log(err) });

5.  配置示例

通过axios实例get/post方法发送请求

执行 GET 请求

// 为给定 ID 的 user 创建请求
axios.get('/user?ID=12345')
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

// 可选地,上面的请求可以这样做
axios.get('/user', {
    params: {
      ID: 12345
    }
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行 POST 请求

axios.post('/user', {
    firstName: 'Fred',
    lastName: 'Flintstone'
  })
  .then(function (response) {
    console.log(response);
  })
  .catch(function (error) {
    console.log(error);
  });

执行多个并发请求

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // 两个请求现在都执行完成
  }));

 

通过axios实例构造方法发送请求

axios(config)

// 发送 POST 请求
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

axios(url[, config])

// 发送 GET 请求(默认的方法)
axios('/user/12345');

创建实例

可以使用自定义配置新建一个 axios 实例

axios.create([config])

var instance = axios.create({
  baseURL: 'https://some-domain.com/api/',
  timeout: 1000,
  headers: {'X-Custom-Header': 'foobar'}
});

配置的默认值/defaults

你可以指定将被用在各个请求的配置默认值

全局的 axios 默认值

axios.defaults.baseURL = 'https://api.example.com';
axios.defaults.headers.common['Authorization'] = AUTH_TOKEN;
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';

自定义实例默认值

// 创建实例时设置配置的默认值
var instance = axios.create({
  baseURL: 'https://api.example.com'
});

// 在实例已创建后修改默认值
instance.defaults.headers.common['Authorization'] = AUTH_TOKEN;

配置的优先顺序

配置会以一个优先顺序进行合并。这个顺序是:在 node_modules/axios/lib/defaults.js 找到的库的默认值,然后是实例的 defaults 属性,最后是请求的 config 参数。后者将优先于前者。这里是一个例子:

// 使用由库提供的配置的默认值来创建实例
// 此时超时配置的默认值是 `0`
var instance = axios.create();

// 覆写库的超时默认值
// 现在,在超时前,所有请求都会等待 2.5 秒
instance.defaults.timeout = 2500;

// 为已知需要花费很长时间的请求覆写超时设置
instance.get('/longRequest', {
  timeout: 5000
});

拦截器

在请求或响应被 then 或 catch 处理前拦截它们。

// 添加请求拦截器
axios.interceptors.request.use(function (config) {
    // 在发送请求之前做些什么
    return config;
  }, function (error) {
    // 对请求错误做些什么
    return Promise.reject(error);
  });

// 添加响应拦截器
axios.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    return response;
  }, function (error) {
    // 对响应错误做点什么
    return Promise.reject(error);
  });

如果你想在稍后移除拦截器,可以这样:

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

可以为自定义 axios 实例添加拦截器

var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

错误处理

axios.get('/user/12345')
  .catch(function (error) {
    if (error.response) {
      // 请求已发出,但服务器响应的状态码不在 2xx 范围内
      console.log(error.response.data);
      console.log(error.response.status);
      console.log(error.response.headers);
    } else {
      // Something happened in setting up the request that triggered an Error
      console.log('Error', error.message);
    }
    console.log(error.config);
  });

可以使用 validateStatus 配置选项定义一个自定义 HTTP 状态码的错误范围。

axios.get('/user/12345', {
  validateStatus: function (status) {
    return status < 500; // 状态码在大于或等于500时才会 reject
  }
})

 

6. 基于axios的请求工具类

import axios from 'axios'
import store from '../vuex/store'

// axios 全局默认配置
axios.defaults.timeout = 1000000
axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8'

// ********************** 加载效果相关 ********************** 
let needLoadingRequestCount = 0
function startLoading () {
  store.commit('updateLoadingStatus', true)
}

function endLoading () {
  store.commit('updateLoadingStatus', false)
}

function showFullScreenLoading () {
  if (needLoadingRequestCount === 0) {
    startLoading()
  }
  needLoadingRequestCount++
}


function tryHideFullScreenLoading () {
  if (needLoadingRequestCount <= 0) return
  needLoadingRequestCount--
  if (needLoadingRequestCount === 0) {
    endLoading()
  }
}
// ********************** 加载效果相关 ********************** 


// ********************** 拦截器相关 ********************** 
axios.interceptors.request.use((config) => {
  let token = localStorage.getItem('tokenKey')
  if (token) {
    config.headers['tokenKey'] = token
  }
  if (config.method === 'post') {
    config.data = JSON.stringify(config.data)
  }  
  showFullScreenLoading()
  return config
}, (error) => {
  return Promise.reject(error)
})


axios.interceptors.response.use((res) => {
  if (!res) {
    return Promise.reject(res)
  } else {
    if (res.data.resultCode === '100004') {
      // '用户未登录, 跳转到登录页面'
      window.location.href = ''
    }
  }
  tryHideFullScreenLoading()
  return res
}, (error) => {
  tryHideFullScreenLoading()
  return Promise.reject(error)
})

// ********************** 拦截器相关 ********************** 

// 创建发送上传请求的axios对象
const axiosT = axios.create({
  headers: {
    'Content-Type': 'multipart/form-data'
  }
})

axiosT.interceptors.request.use((config) => {
  let token = localStorage.getItem('tokenKey')
  if (token) {
    config.headers['tokenKey'] = token
  }
  showFullScreenLoading()
  return config
}, (error) => {
  return Promise.reject(error)
})

axiosT.interceptors.response.use((res) => {
  if (!res) {
    return Promise.reject(res)
  } else {
    if (res.data.resultCode === '100004') {
      // 未登录直接跳转到指定页面
      window.location.href = ''
    }
  }
  tryHideFullScreenLoading()
  return res
}, (error) => {
  tryHideFullScreenLoading()
  return Promise.reject(error)
})


function fetchData (url, params, method = 'get') {
  return new Promise((resolve, reject) => {
    let config = {}
    config = {
      method: method,
      url: url
    }
    // params
    method === 'get' ? config.params = params : config.data = params
    axios(config)
      .then(response => {
        resolve(response.data)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

function formData (url, params, method = 'get') {
  return new Promise((resolve, reject) => {
    let config = {}
    config = {
      method: method,
      url: url
    }
    // params
    method === 'get' ? config.params = params : config.data = params
    axiosT(config)
      .then(response => {
        resolve(response.data)
      })
      .catch((error) => {
        reject(error)
      })
  })
}

export default {
 
  // 查询订单列表
  queryOrderList (params) {
    return fetchData('/***/order/getOrderListData', params, 'post')
  }
  
}

参考:https://www.kancloud.cn/yunye/axios/234845

你可能感兴趣的:(Vue,JavaScript,前端技术)