1.在请求拦截器中,去除参数空格

644 阅读2分钟

浏览器不会改变传参的数据结构,如果数据结构发生了变化,需要排查请求拦截器做了什么操作

在请求拦截器里统一去掉空格

封装公共方法

    export const trimSpace = (data: Record<string, any>) => {
      if (!data) return data;

      if (Object.prototype.toString.call(data) === '[object String]') {
        data = data.trim();
      }

      if (typeof data !== 'object') return data;

      let param = new data.constructor();

      if (Object.prototype.toString.call(data) === '[object Array]') {
        param = data.map((i) => trimSpace(i));
      }

      if (Object.prototype.toString.call(data) === '[object Object]') {
        Object.keys(data).forEach(item => {
          param[item] = trimSpace(data[item]);
        })
      }

      return param
    }

在请求拦截器request.js中使用

    import type { RequestConfig } from '@umijs/max';
    import type { RequestOptions } from '@@/plugin-request/request';
    import {history} from '@umijs/max';
    import { message} from 'antd';
    import { getToken,clearToken } from './authority';
    import { trimSpace } from '@/utils/index';

    // 后端返回response结构, 目前结构都统一这种形式
    interface ResponseStructure {
      config:RequestOptions;
      data:{
        txId: string;
        code: string;
        msg: string;
        data: any;
      }
    }

    /**
     * 后端post请求可能会需要适配几种context-type
     * Content-Type: application/json
     * Content-Type: application/x-www-form-urlencoded
     * Content-Type: multipart/form-data
     */
    export const customRequestConfig: RequestConfig = {
      timeout: 200000,
      baseURL: '/bamBudget/',
      // 请求拦截器
      requestInterceptors: [
        (config: RequestOptions) => {
          let obj = {}
          if(config?.headers){
            obj = config?.headers
          }
          if(Object.keys(obj).length === 7){
            if(window.location.pathname != '/bamBudget/systems/base-page/strategy/strategyUpdate'){
              if (config.data) {
                 // 参数去除空格
                config.data = trimSpace(config.data)
              }
            }
          }
          const token = getToken();
          const headers = {
            ...config.headers,
            "C-Access-Token": token
          }
          return { ...config, headers };
        },
      ],

      // 响应拦截器 后面根据具体接口实际情况进行区分
      responseInterceptors: [
        // @ts-ignore
        (response) => {
          const { data, config } = response as unknown as ResponseStructure;
          // 可以通过传递noResIntercept 这个参数绕过拦截
          if(config?.noResIntercept){
            return response;
          }
          console.log(data.code,'data.code')
          // 登录token没有校验通过
          if(data.code === '401'){
            clearToken();
            if (window.location.pathname !== '/bamBudget/user/login') {
              history.replace({
                pathname: '/user/login',
              })
            }
          }else if(data.code === '10'){
            message.warn(data.msg);
          }else if(data.code === '500'){
            if(data.msg == ''){
              message.error('服务器异常,请联系系统管理员!')
            }
          }else if(data.code==='03' || data.code === '04' || data.code === '07'){
            const err = new Error(data?.msg??'服务器异常,请联系系统管理员!')
            return Promise.reject(err);
          }
          return response;
        },
      ],
    };


在app.js中引入

    // 配置运行时request
    export const request = {
      ...customRequestConfig,
    };

其他封装方法

获取随机数

    export const getUUID = () => {
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
          const r = Math.random() * 16 | 0;
          const v = c === "x" ? r : ((r & 0x3) | 0x8);
          return v.toString(16);
      });
    }

获取url参数,转化为对象格式

    export const parseSearch = <T>(search: string = ''): T => {
      const searchParams: T = {};

      search.slice(1).split('&').forEach((pair) => {
        const temp = pair.split('=');
        searchParams [temp[0]] = temp[1];
      })

      return searchParams;
    }