3328350766
6 天以前 761eb03d6b3bebd0b197179564c84d89d3d12a0d
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
import axios from 'axios'
import { getToken } from '@/utils/auth'
// import { Loading, Message } from 'element-ui'
// import _ from 'lodash'
import cloneDeep from 'lodash/cloneDeep'
export default function axiosFormatting (customConfig) {
  const newCustomConfig = replaceParams(customConfig)
  
  console.log('customConfig: ', customConfig);
  // 将请求头和请求参数的值转化为对象形式
  const httpConfig = {
    timeout: 1000 * 30,
    baseURL: '',
    headers: { 'Content-Type': 'application/json','X-Access-Token': getToken(), ...newCustomConfig.headers }
  }
  // let loadingInstance = null // 加载全局的loading
  const instance = axios.create(httpConfig)
  /** 添加请求拦截器 **/
  instance.interceptors.request.use(config => {
    /**
     * 在这里:可以根据业务需求可以在发送请求之前做些什么。
     * config.headers['token'] = sessionStorage.getItem('token') || ''
     */
    // 执行请求脚本
    // https://mock.presstime.cn/mock/64bf8a00ce1b0ea640809069/test_copy_copy_copy/httpData?token=123&ss=ss
    const req = { ...config, url: {} }
    eval(newCustomConfig.requestScript)
    for (const key in req.url) {
      newCustomConfig.url = replaceUrlParam(newCustomConfig.url, key, req.url[key])
    }
    config = { ...config, ...req, url: newCustomConfig.url }
    return config
  }, error => {
    // 对请求错误做些什么
    return Promise.reject(error)
  })
 
  /** 添加响应拦截器  **/
  instance.interceptors.response.use(response => {
    const resp = response.data
    console.log('resp: ', resp);
    // 执行响应脚本
    if (newCustomConfig.responseScript) {
      // eslint-disable-next-line no-new-func
      const getResp = new Function('resp', newCustomConfig.responseScript)
      const res = getResp(resp)
      return Promise.resolve(res)
    } else {
      return Promise.resolve(resp)
    }
  })
  const body = newCustomConfig?.body.replace(/: ,/g, ':undefined,').replace(/, }/g, ',undefined}')
  /** 发送请求  **/
  return new Promise((resolve, reject) => {
    instance({
      method: newCustomConfig.method,
      url: newCustomConfig.url,
      params: newCustomConfig.params,
      // params 序列化操作
      paramsSerializer: (params) => {
        return Object.keys(params)
          .map(key => {
            if (Array.isArray(params[key])) {
              return params[key].map(value => `${key}=${value}`).join('&')
            } else {
              return `${key}=${params[key]}`
            }
          })
          .join('&')
      },
      data: newCustomConfig.method === 'post' ? body : undefined
    }).then(response => {
      resolve(response)
    }).catch(error => {
      reject(error)
    })
  })
}
// 动态替换url后面参数的值
function replaceUrlParam (url, paramName, paramValue) {
  const regex = new RegExp(`([?&])${paramName}=.*?(&|$)`, 'i')
  const separator = url.indexOf('?') !== -1 ? '&' : '?'
  if (url.match(regex)) {
    return url.replace(regex, `$1${paramName}=${paramValue}$2`)
  } else {
    return `${url}${separator}${paramName}=${paramValue}`
  }
}
// 将参数的值替换掉其他配置中对应属性的值
function replaceParams (customConfig) {
  const newConfig = cloneDeep(customConfig)
  newConfig.url = evalStrFunc(newConfig.paramsList, newConfig.url)
  newConfig.headers = evalArrFunc(newConfig.paramsList, newConfig.headers)
  newConfig.params = evalArrFunc(newConfig.paramsList, newConfig.params)
  newConfig.body = evalStrFunc(newConfig.paramsList, newConfig.body)
  return newConfig
}
function evalStrFunc (paramsList, string) {
  // 取name作为变量名, value作为变量值 { name: '站三', token: '123'}
  const params = paramsList.reduce((acc, cur) => {
    acc[cur.name] = cur.value
    return acc
  }, {})
  // 将url中 ${xxx} 替换成 ${params.xxx}
  const str = string.replace(/\$\{(\w+)\}/g, (match, p1) => {
    return '${params.' + p1 + '}'
  })
  const transformStr = ''
  // 将字符串中的${}替换为变量, 使用eval执行
  eval('transformStr = `' + str + '`')
  return transformStr
}
function evalArrFunc (paramsList, arr) {
  // 取name作为变量名, value作为变量值 { name: '站三', token: '123'}
  const params = paramsList.reduce((acc, cur) => {
    acc[cur.name] = cur.value
    return acc
  }, {})
  // 取name作为变量名, value作为变量值 { _name: '${name}', _token: '${token}'}
  const paramsListObj = arr.reduce((acc, cur) => {
    if (acc[cur.key]) {
      if (Array.isArray(acc[cur.key])) {
        acc[cur.key].push(cur.value)
      } else {
        acc[cur.key] = [acc[cur.key], cur.value]
      }
    } else {
      acc[cur.key] = cur.value
    }
    return acc
  }, {})
 
  // 转成字符串
  const paramsListStr = JSON.stringify(paramsListObj)
 
  // 将url中 ${xxx} 替换成 ${params.xxx}
  const str = paramsListStr.replace(/\$\{(\w+)\}/g, (match, p1) => {
    return '${params.' + p1 + '}'
  })
  const transformStr = ''
  // 将字符串中的${}替换为变量, 使用eval执行
  eval('transformStr = `' + str + '`')
  const obj = JSON.parse(transformStr)
  console.log('obj: ', obj);
 
  return obj
}