• axios详解之实现请求中断


    Axiosvue项目中使用最多的一个第三方开源免费的HTTP库,最大的特点在于可以同时兼容浏览器端和NodeJS服务端。底层通过判定不同的运行环境来自动提供不同的适配器,在浏览器端通过原生的XHR对象来发送请求,而在NodeJS服务端则通过内置的http模块来发送请求。

    1、基础示例

     1 // 安装 axios
     2 npm install --save axios;
     3 
     4 // 导入 axios
     5 import axios from 'axios';
     6 // 创建 axios 实例
     7 const instance = axios.create({
     8   baseURL: 'https://www.some-domain.com/path/to/example',
     9   timeout: 30000,
    10   headers: {
    11     'Content-Type': 'application/x-www-form-urlencoded',
    12   },
    13 });
    14 // 设置 axios 实例默认配置
    15 instance.defaults.headers.common['Authorization'] = '';
    16 instance.defaults.headers.post['Content-Type'] = 'application/json; charset=UTF-8';
    17 
    18 // 自定义请求拦截器
    19 instance.interceptors.request.use(config => {
    20   const token = window.localStorage.getItem('token');
    21   token && (config.headers['Authorization'] = token);
    22   return config;
    23 }, error => Promise.reject(error));
    24 
    25 // 自定义响应拦截器
    26 instance.interceptors.response.use(response => {
    27   if (response.status === 200) {
    28     return Promise.resolve(response.data);
    29   }
    30   
    31   return Promise.reject(response);
    32 }, error => Promise.reject(error));

    2、结合Axios提供的CancelToken构造函数来创建一个简单的post请求

     1 const CancelToken = axios.CancelToken;
     2 let cancel;
     3 
     4 instance.post('/api/user/123', {
     5   name: 'new name',
     6   phone: 'new phone',
     7 }, {
     8   // CancelToken 构造函数接收一个 executor 函数参数,并且该函数接收一个取消函数 c 用于取消该次请求
     9   cancelToken: new CancelToken(function executor(c) {
    10     // 将取消函数赋值到外部变量,方便从外部取消请求
    11     cancel = c;
    12   }),
    13 });
    14 
    15 // 手动取消请求
    16 cancel();

    3、为了避免在每个请求中都需要手动去实例化CancelToken,我们可以巧妙利用request拦截器来整合这部分的逻辑,实现逻辑复用

    3.1、首先将缓存逻辑拆分到一个单独的文件中:

     1 // cacheUtils.js
     2 export const CacheUtils = {
     3   // 存储请求接口地址以及请求体和取消函数之间的映射关系
     4   cache: {},
     5   
     6   // 根据提供的键名 key 取消对应的请求,若未提供则取消全部请求
     7   clearCache: function (key) {
     8     if (key) {
     9       const cancel = this.cache[key];
    10       if (cancel && typeof cancel === 'function') {
    11         cancel();
    12         delete this.cache[key];
    13       }
    14 
    15       return;
    16     }
    17 
    18     Object.keys(this.cache).forEach(cacheKey => {
    19       const cancel = this.cache[cacheKey];
    20       cancel();
    21       delete this.cache[cacheKey];
    22     });
    23   },
    24 };

    3.2、接下来将其应用到请求拦截器和响应拦截器中:

     1 import qs from 'qs';
     2 import { CacheUtils } from './cacheUtils.js';
     3 
     4 // 自定义请求拦截器
     5 instance.interceptors.request.use(config => {
     6   let cacheKey = config.url;
     7   
     8   const token = window.localStorage.getItem('token');
     9   token && (config.headers['Authorization'] = token);
    10   
    11   const method = config.method.toLowerCase();
    12   if (method === 'get' && config.params && typeof config.params === 'object') {
    13     cacheKey += qs.stringify(config.params, { addQueryPrefix: true });
    14   }
    15   
    16   if (['post', 'put', 'patch'].includes(method) && config.data && typeof config.data === 'object') {
    17     config.data = qs.stringify(config.data);
    18     cacheKey += `_${qs.stringify(config.data, { arrayFormat: 'brackets' })}`;
    19   }
    20   
    21   // 每次发送请求之前将上一个未完成的相同请求进行中断
    22   CacheUtils.cache[cacheKey] && CacheUtils.clearCache(cacheKey);
    23   
    24   // 将当前请求所对应的取消函数存入缓存
    25   config.cancelToken = new axios.CancelToken(function executor(c) {
    26     CacheUtils.cache[cacheKey] = c;
    27   });
    28   
    29   // 临时保存 cacheKey,用于在响应拦截器中清除缓存
    30   config.cacheKey = cacheKey;
    31   
    32   return config;
    33 }, error => Promise.reject(error));
    34 
    35 // 自定义响应拦截器
    36 instance.interceptors.response.use(response => {
    37   // 响应接收之后清除缓存
    38   const cacheKey = response.config.cacheKey;
    39   delete CacheUtils.cache[cacheKey];
    40   
    41   if (response.status === 200) {
    42     return Promise.resolve(response.data);
    43   }
    44   
    45   return Promise.reject(response);
    46 }, error => {
    47   // 响应异常清除缓存
    48   if (error.config) {
    49     const cacheKey = error.config.cacheKey;
    50     delete CacheUtils.cache[cacheKey];
    51   }
    52   
    53   return Promise.reject(error);
    54 });

    3.3、同样提供CacheUtils.clearCache函数来应对需要手动清除未完成请求的应用场景,使用方式:

    1 // 网页卸载前清除缓存
    2 window.addEventListener('beforeunload', () => CacheUtils.clearCache(), false);
    3 
    4 // Vue 中路由跳转前清除缓存
    5 router.beforeEach((to, from, next) => { CacheUtils.clearCache(); next(); });

    4、总结:在 axios库中,我们借助于其提供的CancelToken构造函数同样实现了请求中断。

  • 相关阅读:
    Codeforces 429 A. Xor-tree
    有趣的游戏:Google XSS Game
    三层架构(一个)——什么是三层架构?
    atitit.ajax bp dwr 3.该票据安排使用的流量汇总 VO9o.....
    深入struts2.0(五)--Dispatcher类
    update与fixedupdate差别
    Android 平台 HTTP网速測试 案例 API 分析
    Matlab画图-非常具体,非常全面
    词性标注
    windows消息钩子
  • 原文地址:https://www.cnblogs.com/baidei/p/16202139.html
Copyright © 2020-2023  润新知