只对url和方法进行比较:
import axios from 'axios'
import { Message } from 'element-ui'
import route from '@/router'
const duration = 2 * 1000
let preDate = 0
const Cancel = axios.CancelToken
let httpPending = []
function removeHttpPending(config) {
// console.log(config)
httpPending.map((item, index, arr) => {
// console.log(item)
if (item.u === config.url + '&' + config.method) {
console.log(`${config.url}: 短时间内重复请求`)
item.f()
arr.splice(index, 1)
}
return config
})
}
function clearHttpPending() {
httpPending = []
}
// create an axios instance
const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
withCredentials: true, // send cookies when cross-domain requests
headers: { 'From': 'browser' },
timeout: 30000 // request timeout
})
// 当有重复请求的时候,就删除前一个请求
service.interceptors.request.use((config) => {
removeHttpPending(config)
config.cancelToken = new Cancel(c => {
httpPending.push({ u: config.url + '&' + config.method, f: c })
})
return config
}, (err) => {
return Promise.reject(err)
})
// response interceptor
service.interceptors.response.use(
/**
* If you want to get http information such as headers or status
* Please return response => response
*/
/**
* Determine the request status by custom code
* Here is just an example
* You can also judge the status by HTTP Status Code
*/
response => {
clearHttpPending()
const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (!res.success) {
Message({
message: res.message || 'Error',
type: 'error',
duration: duration
})
return Promise.reject(new Error(res.message || 'Error'))
} else {
return res
}
},
error => {
const date = new Date().getTime()
if ((date - preDate) > 2000) {
preDate = date
console.log('err' + error) // for debug
if (error.response.status === 401) {
route.push('/login')
} else {
Message({
message: error.response.data.message,
type: 'error',
duration: duration
})
}
}
return Promise.reject(error)
}
)
export default service
加上对参数的校验:
function removeHttpPending(config) {
httpPending.map((item, index, arr) => {
if (item.u === config.url + '&' + config.method) {
if (!(item.data && isSameKeyValueObj(item.data, config.data)) && !(item.params && isSameKeyValueObj(item.params, config.params))) {
return config
}
console.warn(`${config.url}: 短时间内重复请求`)
item.f()
arr.splice(index, 1)
}
return config
})
}
function isObj(obj) {
const str = Object.prototype.toString.call(obj)
if (str === '[object Object]' || str === '[object Array]') {
return true
}
return false
}
function isSameKeyValueObj(target, source) {
if (!isObj(target) || !isObj(source)) {
return false
}
const targetkeys = Object.getOwnPropertyNames(target)
const sourcekeys = Object.getOwnPropertyNames(source)
if (targetkeys.length !== sourcekeys.length) {
return false
}
for (let i = 0; i < targetkeys.length; i++) {
const key = targetkeys[i]
if (!isObj(target[key]) && target[key] !== source[key]) {
return false
}
if (isObj(target[key])) {
return isSameObj(target[key], source[key])
}
}
return true
}
http.interceptors.request.use((config) => {
removeHttpPending(config)
config.cancelToken = new Cancel(c => {
httpPending.push({
u: config.url + '&' + config.method,
f: c,
data: config.data,
params: config.params
})
})
return config
}, (err) => {
return Promise.reject(err)
})