• vue3 请求响应拦截


      

    import axios, { AxiosInstance } from 'axios';
    import { ElMessage, ElMessageBox } from 'element-plus';
    import { MessageType } from 'element-plus/lib/el-message/src/types';
    import { Base64 } from 'js-base64';
    import { IRequests, ServiceOptions, SvcParams, whiteListUrl } from '../model/requst';
    import { RESPONSETYPE } from '../model/requst';
    import store from '../store';
    import { getTenant, getToken } from './auth';
    
    // 预防 出现option跨域请求
    axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
    let invalidationMark = true;
    
    const servicesOptions:ServiceOptions = {
      mesRequest: {
        timeout: 60000,
        baseURL: `${import.meta.env.VITE_APP_BASE_API}`,
        // withCredentials: true
      }
    }
    
    function permissionHandler() {
      if (invalidationMark) {
        invalidationMark = false;
        ElMessageBox.alert(
          '你已被登出,可以取消继续留在该页面,或者重新登录',
          '确定登出',
          {
            confirmButtonText: '确定',
            callback: () => {
              store.dispatch('FedLogOut').then(() =>{
                location.reload(); // 莫名其妙代码
              });
              invalidationMark = true;
            }
          }
        )
      }
    }
    
    function arrayBufferHandler(responseData: Iterable<number>) {
      const enc = new TextDecoder('utf-8');
      const errorData = JSON.parse(enc.decode(new Uint8Array(responseData)));
      return errorData;
    }
    
    function messageHandler(msg: string, type: MessageType) {
      ElMessage({
        message: msg,
        type: type,
        duration: 3000
      });
    }
    
    function decorateService(service: AxiosInstance) {
      // 请求拦截
      service.interceptors.request.use(
        // 请求配置
        (config) => {
          const clientId = import.meta.env.VITE_APP_CLIENT_ID;
          const clientSecret = import.meta.env.VITE_APP_CLIENT_SECRET;
          const isToken = config.headers['X-isToken'] === false ? config.headers['X-isToken'] : true;
          const isTenant = config.headers['X-isTenant'] === false ? config.headers['X-isTenant'] : true
            && import.meta.env.VITE_APP_IS_MULTI_TENANT_TYPE !== "NONE";
          isToken && (config.headers.token = 'Bearer ' + getToken());
          isTenant && (config.headers.tenant = getTenant());
          config.headers['Authorization'] = `Basic ${Base64.encode(`${clientId}:${clientSecret}`)}`;
          return config;
        },
        (error) => {
          Promise.reject(error);
        }
      );
      service.interceptors.response.use(
        (response) => {
          const responseData = response.data;
          const url = response.config.url?.substring(0, response.config.url.lastIndexOf('/'));
          const isWhite = url && whiteListUrl.includes(url);   
          const contentType = response.headers['content-type'];
          const isJson = contentType && contentType === 'application/json; charset=UTF-8';
          if (responseData.code === 0 || !isJson) {
            return Promise.resolve(responseData);
          }
          !isWhite && messageHandler(responseData.msg, 'error');
          return Promise.reject(responseData);
        },
        (error) => {
          const responseType = error.config?.responseType;
          const errorData = responseType === RESPONSETYPE.ARRAYBUFFER ? arrayBufferHandler(error.response.data) : error.response?.data;
          const status = error.response?.status
          switch(status) {
            case 500:
            case 501:
            case 502:
            case 503:
              messageHandler('服务暂未启动,请稍等一会儿再试~~', 'error');
              return Promise.reject(Error('服务暂未启动'));
            case 401:
              return permissionHandler();
            default:
              const msg = errorData?.msg || errorData?.errorMsg || '系统内部异常,请联系网站管理员';
              messageHandler(msg, 'error');
              return Promise.reject(errorData);
          }
        }
      )
    }
    
    function getServices(options: ServiceOptions): IRequests {
      const requests:IRequests = {};
      Object.keys(options).forEach((svcName) => {
        requests[svcName] = axios.create(options[svcName as SvcParams]);
        decorateService(requests[svcName]);
      });
      return requests;
    }
    
    export default getServices(servicesOptions);
    

      

    // requst的接口
    
    import type { AxiosInstance, AxiosRequestConfig } from "axios";
    
    export const whiteListUrl = [
      '/componentBom/batchImport',
      '/componentBom/importBomBasic',
      '/componentBom/importMaterial',
      '/componentBom/importBomRebar',
      '/stackLoadPlan/planImport'
    ] 
    
    export const RESPONSETYPE = {
      ARRAYBUFFER: 'arraybuffer',
      BLOB: 'blob',
      DOCUMENT: 'document',
      JSON: 'json',
      STREAM: 'stream',
      TEXT: 'text',
    }
    
    export interface ServiceOptions {
      mesRequest: AxiosRequestConfig;
    }
    
    export interface IRequests {
      [axiosSvcName: string]: AxiosInstance
    }
    
    export type SvcParams = 'mesRequest';
    

      

  • 相关阅读:
    关于方差所引发的遐想
    POJ 1390 Blocks
    POJ 1722 SUBTRACT
    BZOJ 1901 Dynamic Rankings
    关于Shine-hale
    ACM恢复训练(一)最短路
    CSP退役记
    校内模拟赛(三)(9.24)
    校内模拟赛(二)(9.12)
    校内模拟赛(一)(2019.9.10)
  • 原文地址:https://www.cnblogs.com/daifuchao/p/15797669.html
Copyright © 2020-2023  润新知