ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

vue3 请求响应拦截

2022-01-13 15:04:41  阅读:166  来源: 互联网

标签:const headers error 响应 vue3 import 拦截 config response


  

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';

  

标签:const,headers,error,响应,vue3,import,拦截,config,response
来源: https://www.cnblogs.com/daifuchao/p/15797669.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有