Sprinkler-app/common/http.interceptor.js

154 lines
4.1 KiB
JavaScript
Raw Normal View History

2026-06-18 11:31:43 +08:00
const NO_NETWORK_TEXT = '当前无网络,请检查网络连接'
let isNetworkOnline = true
let hasBoundNetworkListener = false
let hasBoundRequestInterceptor = false
let hasPatchedUviewRequest = false
let lastNoNetworkToastAt = 0
const showNoNetworkToast = () => {
const now = Date.now()
if (now - lastNoNetworkToastAt < 2000) return
lastNoNetworkToastAt = now
uni.showToast({
title: NO_NETWORK_TEXT,
icon: 'none',
duration: 2000
})
}
const updateNetworkOnlineStatus = (online) => {
isNetworkOnline = !!online
}
const initNetworkStatus = () => {
try {
const sysInfo = uni.getSystemInfoSync()
if (sysInfo && typeof sysInfo.networkType === 'string') {
updateNetworkOnlineStatus(sysInfo.networkType !== 'none')
}
} catch (e) {}
}
const refreshNetworkStatusSync = () => {
try {
const sysInfo = uni.getSystemInfoSync()
if (sysInfo && typeof sysInfo.networkType === 'string') {
updateNetworkOnlineStatus(sysInfo.networkType !== 'none')
}
} catch (e) {}
return isNetworkOnline
}
const bindNetworkStatusListener = () => {
if (hasBoundNetworkListener) return
hasBoundNetworkListener = true
uni.onNetworkStatusChange((res) => {
updateNetworkOnlineStatus(res && res.isConnected)
if (res && res.isConnected === false) {
showNoNetworkToast()
}
})
}
const bindGlobalRequestInterceptor = () => {
if (hasBoundRequestInterceptor || typeof uni.addInterceptor !== 'function') return
hasBoundRequestInterceptor = true
uni.addInterceptor('request', {
invoke() {
if (!refreshNetworkStatusSync()) {
showNoNetworkToast()
return false
}
},
fail(err) {
const msg = (err && err.errMsg) ? String(err.errMsg).toLowerCase() : ''
if (msg.includes('fail') && (msg.includes('network') || msg.includes('internet') || msg.includes('offline'))) {
updateNetworkOnlineStatus(false)
showNoNetworkToast()
}
}
})
}
const isLikelyNetworkError = (err) => {
const msg = err && err.errMsg ? String(err.errMsg).toLowerCase() : String(err || '').toLowerCase()
if (!msg) return false
return (
msg.includes('request:fail') ||
msg.includes('network') ||
msg.includes('internet') ||
msg.includes('offline') ||
msg.includes('timeout') ||
msg.includes('disconnected') ||
msg.includes('dns')
)
}
2023-12-05 16:45:28 +08:00
const install = (Vue, vm) => {
2026-06-18 11:31:43 +08:00
initNetworkStatus()
bindNetworkStatusListener()
bindGlobalRequestInterceptor()
2024-03-13 10:54:22 +08:00
Vue.prototype.$u.http.setConfig({
2026-06-18 11:31:43 +08:00
baseUrl: 'https://yxd.ccttiot.com/prod-api',
// baseUrl: 'http://192.168.1.5:8081',
loadingText: '',
loadingTime: 800,
// 设置自定义头部content-type
header: {
'content-type': 'application/json;charset=UTF-8',
},
// ......
})
// 为uView请求增加统一网络失败兜底避免页面忘记catch时控制台刷错
if (!hasPatchedUviewRequest) {
hasPatchedUviewRequest = true
const rawRequest = Vue.prototype.$u.http.request.bind(Vue.prototype.$u.http)
Vue.prototype.$u.http.request = (options = {}) => {
if (!refreshNetworkStatusSync()) {
showNoNetworkToast()
// 与uView拦截return false行为保持一致中断后不进入then/catch
return new Promise(() => {})
}
return rawRequest(options).catch((err) => {
if (isLikelyNetworkError(err)) {
updateNetworkOnlineStatus(false)
showNoNetworkToast()
return new Promise(() => {})
}
return Promise.reject(err)
})
}
}
// 请求拦截部分,如配置,每次请求前都会执行
2023-12-05 16:45:28 +08:00
Vue.prototype.$u.http.interceptor.request = (config) => {
2026-06-18 11:31:43 +08:00
if (!refreshNetworkStatusSync()) {
showNoNetworkToast()
// 返回false可中断请求uView内置约定
return false
}
config.header = config.header || {}
const token = uni.getStorageSync('token')
config.header.Authorization = token
2023-12-06 10:06:54 +08:00
// config.header.Tenant-Id=1
2023-12-05 16:45:28 +08:00
// #ifdef H5
2026-06-18 11:31:43 +08:00
config.header.Authorization = 'Bearer ' + token
2023-12-05 16:45:28 +08:00
// #endif
// 可以对某个url进行特别处理此url参数为this.$u.get(url)中的url值
2026-06-18 11:31:43 +08:00
if (config.url == '/user/login') config.header.noToken = true
2023-12-05 16:45:28 +08:00
// 最后需要将config进行return
2026-06-18 11:31:43 +08:00
return config
2023-12-05 16:45:28 +08:00
}
2026-06-18 11:31:43 +08:00
2023-12-05 16:45:28 +08:00
// 响应拦截,如配置,每次请求结束都会执行本方法
2026-06-18 11:31:43 +08:00
Vue.prototype.$u.http.interceptor.response = (res) => {
return res
}
2023-12-05 16:45:28 +08:00
}
export default {
install
2026-06-18 11:31:43 +08:00
}