• 封装axios


    import axios from 'axios';
    import qs from 'qs';
    import vMessage from '@/components/messageTips';
    
    const service = axios.create({
      // 请求超时时间
      // timeout: 3000
    });
    // service.defaults.withCredentials = true;
    
    // 请求拦截器
    service.interceptors.request.use(
      async config => {
        if (config.url.indexOf('login') > 0) { // 部分接口不需要验证token,如登录
          // 下面5个数据  都是登陆后就放入localStorage的
          let tenantToken = localStorage.getItem('tenant_token'); // token
          const tenantId = localStorage.getItem('tenantId'); // 业务所需
          const userId = localStorage.getItem('userId'); // 业务所需
          const expTime = localStorage.getItem('exp_time'); // token失效时间点(ms)
          const refreshTime = localStorage.getItem('refresh_time'); // 时间长度(ms)
          if (expTime !== 'permanent') {
            // 校验token有效期
            let nowTime = '';
            const [err, res] = await to(axios.head(`${window.projectConfig.asiaInfoUrl}/tenant/time`));
            if (!err && res) {
              nowTime = new Date(res.headers.date).getTime();
              // 若token有效期到今日10点,refreshTime=5分钟,若用户在9:55-10:00之间仍然在调用接口,则重新获取新的token,并保存新token的信息,下次请求中携带新token,可避免用户操作过程中,突然返回登录页的尴尬
              // 当前时间>失效时间-token刷新时间,获取新token,失效时间重新开始计算,此过程用户无感知
              if (nowTime > expTime - refreshTime && nowTime < expTime) {
                const [err2, res2] = await asyncPost('tenant/t_refresh_token', qs.stringify({
                  tenant_id: tenantId,
                  user_id: userId,
                  token: tenantToken
                }));
                if (!err2 && res2) {
                  tenantToken = res2.data.result.tenant_refreshToken;
                  localStorage.setItem('tenant_token', tenantToken);
                  localStorage.setItem('exp_time', res2.data.result.exp_time);
                }
              }
            }
          } else {
            // 当expTime==='permanent' 不需要校验token有效期
          }
          config.headers.tenant_token = tenantToken;
        }
        return config;
      },
      err => {
        console.log(err);
      }
    );
    
    service.interceptors.response.use(
      response => {
        if (response.status === 200) {
          return response;
        } else {
          // router.replace('/403');
        }
      },
      err => {
        // console.log(err.request);
        if (err.request.status === 510) {
          vMessage.error('token校验异常,请重新登录');
          localStorage.clear();
          // 退出登录时,需要将vuex中的变量全部还原为初始化值,如果用$router跳转无法还原
          window.location = 'login';
          // return Promise.resolve(err.response);
          // return err.response;
        } else {
          return Promise.reject(err);
        }
      }
    );
    
    const formatUrl = url => {
      let returnUrl = '';
      if (url.startsWith('http://') || url.startsWith('https://')) {
        returnUrl = url;
      } else {
        // 传递的url不能以 '/' 开头,否则拼接后的url会存在双斜杠,可能会导致服务器报错
        if (url.startsWith('/')) {
          console.error(`url=${url},此url错误,请勿以'/'开头,`);
          returnUrl = 'error';
        } else {
          returnUrl = `${window.projectConfig.asiaInfoUrl}/${url}`;
        }
      }
      return returnUrl;
    };
    
    // 此方法是为了方便使用axios.all
    const getPromise = (url, params, config) => {
      const newUrl = formatUrl(url);
      if (newUrl === 'error') {
        return;
      }
      const obj = Object.assign({
        url: newUrl,
        method: 'get',
        params
      }, config);
      return service(obj);
    };
    
    const asyncGet = (url, params, config, errorExt) => {
      const promise = getPromise(url, params, config);
      return to(promise, errorExt);
    };
    
    // 此方法是为了方便使用axios.all
    const downloadPromise = (url, params, config) => {
      const newUrl = formatUrl(url);
      if (newUrl === 'error') {
        return;
      }
      const obj = Object.assign({
        url: newUrl,
        method: 'get',
        params,
        responseType: 'arraybuffer'
      }, config);
      return service(obj);
    };
    
    const asyncDownload = (url, params, config, errorExt) => {
      const promise = downloadPromise(url, params, config);
      return to(promise, errorExt);
    };
    
    // 此方法是为了方便使用axios.all
    const postPromise = (url, data, config) => {
      const newUrl = formatUrl(url);
      if (newUrl === 'error') {
        return;
      }
      const obj = Object.assign({
        url: newUrl,
        method: 'post',
        data
      }, config);
      return service(obj);
    };
    
    const asyncPost = (url, data, config, errorExt) => {
      const promise = postPromise(url, data, config);
      return to(promise, errorExt);
    };
    
    // 此方法是为了方便使用axios.all
    const putPromise = (url, data, config) => {
      const newUrl = formatUrl(url);
      if (newUrl === 'error') {
        return;
      }
      const obj = Object.assign({
        url: newUrl,
        method: 'put',
        data
      }, config);
      return service(obj);
    };
    
    const asyncPut = (url, data, config, errorExt) => {
      const promise = putPromise(url, data, config);
      return to(promise, errorExt);
    };
    
    // 此方法是为了方便使用axios.all
    const deletePromise = (url, params, config) => {
      const newUrl = formatUrl(url);
      if (newUrl === 'error') {
        return;
      }
      const obj = Object.assign({
        url: newUrl,
        method: 'delete',
        params
      }, config);
      return service(obj);
    };
    
    const asyncDelete = (url, params, config, errorExt) => {
      const promise = deletePromise(url, params, config);
      return to(promise, errorExt);
    };
    
    // 读取本地文件
    const readLocalFile = (url, params, config, errorExt) => {
      const obj = Object.assign({
        url: url,
        method: 'get',
        params
      }, config);
      return to(service(obj), errorExt);
    };
    
    const to = (promise, errorExt = '未知错误') => {
      return promise
        .then(function (data) {
          return [null, data];
        })
        .catch(function (err) {
          if (errorExt) {
            Object.assign(err, { errorExt });
          }
          if (err.code === 'ECONNABORTED' && err.message.indexOf('timeout') !== -1) {
            vMessage.error(`请求超时 [ 错误编码:${err.request.status} ]`);
          } else if (err.message.indexOf('Network Error') !== -1) {
            vMessage.error(`网络异常 [ 错误编码:${err.request.status} ]`);
          } else if (err.request.status === 403) {
            vMessage.error(`无访问权限 [ 错误编码:${err.request.status} ]`);
          } else if (err.request.status === 404) {
            vMessage.error(`请求资源不存在 [ 错误编码:${err.request.status} ]`);
          } else if (err.request.status === 460) {
            vMessage.error(`token错误 [ 错误编码:${err.request.status} ]`);
          } else {
            if (err.request.status !== undefined) {
              vMessage.error(`系统繁忙,请稍后再试 [ 错误编码:${err.request.status} ]`);
            } else {
              vMessage.error('系统繁忙,请稍后再试');
            }
          }
          return [err, undefined];
        });
    };
    
    const handleStream = function (res, fileName) {
      const blob = new Blob([res], { type: 'application/octet-stream' });
      if (typeof window.navigator.msSaveBlob !== 'undefined') {
        window.navigator.msSaveBlob(blob, fileName);
      } else {
        const URL = window.URL || window.webkitURL;
        const objectUrl = URL.createObjectURL(blob);
        const a = document.createElement('a');
        // safari doesn't support this yet
        if (typeof a.download === 'undefined') {
          window.location = objectUrl;
        } else {
          a.href = objectUrl;
          a.download = fileName;
          document.body.appendChild(a);
          a.click();
          a.remove();
        }
      }
    };
    
    const exportObj = {
      service,
      to,
      getPromise,
      postPromise,
      putPromise,
      deletePromise,
      asyncGet,
      asyncPost,
      asyncPut,
      asyncDelete,
      asyncDownload,
      handleStream,
      readLocalFile
    };
    
    export default exportObj;
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180
    • 181
    • 182
    • 183
    • 184
    • 185
    • 186
    • 187
    • 188
    • 189
    • 190
    • 191
    • 192
    • 193
    • 194
    • 195
    • 196
    • 197
    • 198
    • 199
    • 200
    • 201
    • 202
    • 203
    • 204
    • 205
    • 206
    • 207
    • 208
    • 209
    • 210
    • 211
    • 212
    • 213
    • 214
    • 215
    • 216
    • 217
    • 218
    • 219
    • 220
    • 221
    • 222
    • 223
    • 224
    • 225
    • 226
    • 227
    • 228
    • 229
    • 230
    • 231
    • 232
    • 233
    • 234
    • 235
    • 236
    • 237
    • 238
    • 239
    • 240
    • 241
    • 242
    • 243
    • 244
    • 245
    • 246
    • 247
    • 248
    • 249
    • 250
    • 251
    • 252
    • 253
    • 254
    • 255
    • 256
    • 257
    • 258
    • 259
    • 260
    • 261
    • 262
    • 263
    • 264
    • 265
    • 266
    • 267
  • 相关阅读:
    C语言实现带头双向循环链表
    《MongoDB》Mongo Shell中的基本操作-更新操作一览
    Java EnumMap keySet()方法具有什么功能呢?
    uni-app下Worker的使用
    Java进公司首先要做的准备工作-maven、idea、Tomcat安装和配置
    【Java】Java基础习题1
    FFMPEG音视频开发指南(一)
    【故障公告】cc攻击又来了,雪上加霜的三月
    如何在 SAP Spartacus 中编写 ASM-Compatible 的代码
    安全机制(security) - 加解密算法 - 对称加密 - 加解密模式
  • 原文地址:https://blog.csdn.net/My_Java_Life/article/details/125526740