fix
13404089107
6 天以前 a90bcdf047a8baf02aeec81221aeeb49db523cde
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
import axios from 'axios'
import apiConfig from './baseurl'
import store from '@/store' // 导入 Vuex store
import CryptoJS from 'crypto-js';
 
import {
  Message
} from 'element-ui'
 
const service = axios.create({
  baseURL: apiConfig.baseURL,
  withCredentials: false, // 当跨域请求时发送cookie
  timeout: 60000, // request timeout
})
// 对 POST 请求参数进行排序
const sortPostParams = (params) => {
  const keys = Object.keys(params);
 
  keys.sort((a, b) => {
    for (let i = 0; i < Math.min(a.length, b.length); i++) {
      const asciiA = a.charCodeAt(i);
      const asciiB = b.charCodeAt(i);
 
      if (asciiA !== asciiB) {
        return asciiA - asciiB;
      }
    }
 
    // 如果两个字符串长度不同,则较短的字符串排在前面
    return a.length - b.length;
  });
 
  const sortedParams = {};
  keys.forEach(key => {
    sortedParams[key] = params[key];
  });
 
  return sortedParams;
}
//去除对象中空值的属性
const removeEmptyProperties = (obj) => {
  return Object.fromEntries(Object.entries(obj).filter(([key, value]) => value !== undefined && value !== null && value !== '' && (Array.isArray(value) ? value.length > 0 : true)));
};
// 将对象转换为字符串用&拼接
const objToString = (obj) => {
  // 使用 Object.keys() 获取对象的 key 数组
  const keys = Object.keys(obj);
 
  // 使用 Array.prototype.map() 将每个 key-value 对转化为字符串
  const strArray = keys.map(key => {
 
    const value = obj[key];
    if (Array.isArray(value) || typeof value === 'object' && value !== null) {
      return '';
    } else {
      return `${key}=${value}`;
    }
  });
 
  // 使用 Array.prototype.filter() 过滤掉空字符串
  const filteredStrArray = strArray.filter(str => str !== '');
 
  // 使用 Array.prototype.join() 将字符串数组拼接成一个字符串
  const str = filteredStrArray.join('&');
  return str;
}
// 生成随机字符串
const generateRandomString = (length) => {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  const str = [];
  for (let i = 0; i < length; i++) {
    const randomIndex = Math.floor(Math.random() * chars.length);
    str.push(chars[randomIndex]);
  }
  return str.join('');
}
// 对字符串进行 HMAC-SHA1 加密
const encryptWithHMACSHA1 = (message, secret) => {
  return CryptoJS.HmacSHA1(message, secret).toString(CryptoJS.enc.Base64);
};
 
// 请求拦截
service.interceptors.request.use(
  config => {
    const o = config
    let { data, method } = o
    const Authorization = localStorage.getItem('token') || ''
    if (method == 'post') {
      let copyData = JSON.parse(JSON.stringify(data))
      // 对 POST 请求参数进行处理
      let sortData = sortPostParams(copyData)
      sortData = removeEmptyProperties(sortData)
      // 将处理后的 POST 请求参数转换为字符串
      let strData = objToString(sortData)
      // 生成随机字符串  用作加密秘钥
      let nonce_str = generateRandomString(16)
      // 对字符串进行 HMAC-SHA1 加密 并转化为 Base64
 
      let sign = encryptWithHMACSHA1(strData, nonce_str)
      o.headers = {
        ...o.headers,
        timestamp: new Date().getTime(),
        sign,
        nonce_str,
        Authorization,
        client: localStorage.getItem('client')
      }
    } else {
      o.headers = {
        timestamp: new Date().getTime(),
        ...config.headers,
        Authorization,
        client: localStorage.getItem('client')
      }
    }
    return { ...o };
  },
  error => {
    return Promise.reject(error)
  }
)
 
// 响应拦截
service.interceptors.response.use(
  response => {
    if (!response) {
      return
    }
    const res = response;
    if (res.data.code == 200) {
      if (!res.data.data) {
        return Promise.resolve({})
      }
      return Promise.resolve(res.data.data)
    } else {
      if (res.data.code == 103 || res.data.code == 401) {
        Message({
          message: res.data.msg || '登录已过期,请重新登录',
          type: 'warning',
          duration: 2000
        })
        store.commit('clearToken')
        window.location.replace(`/`);
        return Promise.reject(res.data.data)
      }
      Message({
        message: res.data.msg || '服务器错误',
        type: 'error',
        duration: 4000
      })
      return Promise.reject(res.data.data)
    }
  },
  error => {
    Message({
      message: error.message,
      type: 'error',
      duration: 5000
    })
    return Promise.reject(error)
  }
)
 
export default service