axios基本配置、拦截器、取消请求、无感刷新token

1,540 阅读4分钟
1. axios常用基本配置
  • axios请求是JSON格式的,所有属性都在一个对象内;
  1. url:是用于请求的服务器 URL,举例:

{url: '/user'}

  1. method:是创建请求时使用的方法,举例:

{method: 'get'} // get也是method的默认值

  1. baseURL:将自动加在 url 前面,除非 url 是一个绝对 URL,它可以通过设置一个 baseURL 便于为 axios 实例的方法传递相对 URL,举例:

{baseURL: '<https://some-domain.com/api/>'}

  1. transformRequest:允许在向服务器发送前,修改请求数据,它只能用于 'PUT', 'POST' 和 'PATCH' 这几个请求方法,数组中最后一个函数必须返回一个字符串, 一个Buffer实例,ArrayBuffer,FormData,或 Stream,你可以修改请求头,举例:
{
    transformRequest: [function (data, headers) {
    // 对发送的 data 进行任意转换处理

        return data;

    }]
}
  1. transformResponse:在传递给 then/catch 前,允许修改响应数据,举例:
{
    transformResponse: [function (data) {
    // 对接收的 data 进行任意转换处理

        return data;

    }]
}
  1. headers: {'X-Requested-With': 'XMLHttpRequest'},自定义请求头
  2. params:是与请求一起发送的 URL 参数,必须是一个简单对象或 URLSearchParams 对象,举例:
{
    params: {
    ID: 12345
    }
}
  1. paramsSerializer:是可选方法,主要用于序列化params,举例:
{
    paramsSerializer: function (params) {
        return Qs.stringify(params, {arrayFormat: 'brackets'})
    }
}
  1. data:是作为请求体被发送的数据,仅适用 'PUT', 'POST', 'DELETE 和 'PATCH' 请求方法,在没有设置 transformRequest 时,则必须是string, plain object, ArrayBuffer, ArrayBufferView,【 FormData, File, Blob(浏览器专属)】、【Stream, Buffer(Node 专属)】,举例:
{
    data: {
        firstName: 'Fred'
    }
}
  • 发送请求体数据的可选语法,请求方式 post,只有 value 会被发送,key 则不会,data: 'Country=Brasil\&City=Belo Horizonte'

10.timeout:指定请求超时的毫秒数,如果请求时间超过 timeout 的值,则请求会被中断,举例: {timeout: 1000}

  1. withCredentials:表示跨域请求时是否需要使用凭证,举例:

{withCredentials: false, // default}

  1. adapter: 允许自定义处理请求,这使测试更加容易,返回一个 promise 并提供一个有效的响应,举例:
{
    adapter: function (config) {
        /\* ... \*/
    }
}
  1. auth:HTTP Basic Auth,举例:
{
    auth: {
        username: 'janedoe',
        password: 's00pers3cret'
    }
}
  1. responseType:表示浏览器将要响应的数据类型,选项包括: 'arraybuffer', 'document', 'json', 'text', 'stream',浏览器专属:'blob',举例:

{responseType: 'json'}

  1. responseEncoding:表示用于解码响应的编码 (Node.js 专属),注意:忽略 responseType 的值为 'stream',或者是客户端请求,

{responseEncoding: 'utf8' // 默认值}

  1. xsrfCookieName:是 xsrf token 的值,被用作 cookie 的名称,举例:

{xsrfCookieName: 'XSRF-TOKEN'}

  1. xsrfHeaderName:是带有 xsrf token 值的http 请求头名称,举例:

{xsrfHeaderName: 'X-XSRF-TOKEN'}

  1. onUploadProgress:允许为上传处理进度事件,浏览器专属,举例:
{
    onUploadProgress: function (progressEvent) {
        // 处理原生进度事件
    }
}
  1. onDownloadProgress:允许为下载处理进度事件,浏览器专属,举例:
{
    onDownloadProgress: function (progressEvent) {
        // 处理原生进度事件
    }
}
  1. maxContentLength:定义了node.js中允许的HTTP响应内容的最大字节数,举例:

{maxContentLength: 2000}

21.maxBodyLength:(仅Node)定义允许的http请求内容的最大字节数,举例: {maxBodyLength: 2000}

  1. validateStatus:定义了对于给定的 HTTP状态码是 resolve 还是 reject promise,如果 validateStatus 返回 true (或者设置为 nullundefined),则promise 将会 resolved,否则是 rejected,举例:
{
    validateStatus: function (status) {
        return status >= 200 && status < 300; // 默认值
    }
}
  1. maxRedirects:定义了在node.js中要遵循的最大重定向数,如果设置为0,则不会进行重定向,举例:

{maxRedirects: 5, // 默认值}

  1. socketPath:定义了在node.js中使用的UNIX套接字,只能指定 socketPathproxy,若都指定,则使用 socketPath,举例:

{socketPath: null, // default}

  1. proxy:定义了代理服务器的主机名,端口和协议,可以使用常规的http_proxyhttps_proxy 环境变量,使用 false 可以禁用代理功能,同时环境变量也会被忽略,auth表示应使用HTTP Basic auth连接到代理,并且提供凭据,将设置一个 Proxy-Authorization 请求头,它会覆盖 headers 中已存在的自定义 Proxy-Authorization 请求头,如果代理服务器使用 HTTPS,则必须设置 protocol 为https,举例:
{
    proxy: {
            protocol: 'https',
            host: '127.0.0.1',
            port: 9000,
            auth: {
            username: 'mikeymike',
            password: 'rapunz3l'
        }
    }
}
2. 拦截器封装及使用
  1. 使用axios的拦截器封装
import Axios from 'axios';

// 一般是对实例进行拦截器配置
export const reqInstance = Axios.create({
    baseURL:'/api'
  });
// 请求之前的行为
reqInstance.interceptors.request.use(config => {
  console.log('请求发起前..loading..');
},);

reqInstance.interceptors.response.use(response => {
  console.log('响应回来后...关闭loading');
  1. 调用拦截器的方法
testInterceptor() {
    reqInstance.get('/')
        .then(res => {
            console.log(res, 'res')
        })
        .catch(err => {
            console.log('err:', err);
        })
}
3. 使用拦截器实现无感刷新token
  • 用户登录一个页面,token会在一定时间内过期,过期了就需要用户重新登录,为了提升用户体验,可以使用无感刷新token技术,在token刷新后再次调用存储的请求;
  • 无感刷新token: [缓存请求,后续再发];
  1. 实现
  • 定义一个flag,用来控制是直接执行还是缓存当前请求;
  • 如果flag === 'needResfresh',就暂停当前的请求(返回一个padding状态的Promise);
  • 后续可以在resolve中再次发起之前的请求;
let flag = 'needResfresh';
// 请求之前的行为
reqInstance.interceptors.request.use(config => {
  // 无感刷新token: [缓存请求,后续再发]
  if (flag === 'needResfresh') {
    flag = 'second'; // 不再执行当前代码
    // 1. 暂停当前的请求(padding状态的Promise)
    return new Promise((resolve => {
      window.callback = function () {
        // 1. Promise放行 : 参数 
        resolve(reqInstance(config)); // 发起之前的请求
      }
    }));
  }
  else if (flag === 'second') {
    flag = null;
    // 先刷新token
    window.callback(); // 释放后续请求
    return reqInstance(config); // 发情当前请求 register2
  }
  // 2. 发送之前暂停的请求
  return config;
},);
}
4. 取消请求(AbortController)
  • 在请求进行一半时可以手动终止请求;(比如下载时取消下载)
import Axios from 'axios';
export const request = Axios.create({
    baseURL: '/',
    timeout: 8000, // 避免占据并发请求
});

request.interceptors.request.use((config) => {

    console.log('请求开始了');
    const controller = new AbortController();
    config.signal = controller.signal;
    request[config.url] = controller;
    return config;
})

request.interceptors.response.use(response => {
    // 取消请求
    console.log('取消请求方法', request[response.config.url])
    // reqInstance[config.url].abort();
    return response;
});