Sprinkler-app/common/http.interceptor.js
2026-06-18 11:31:43 +08:00

154 lines
4.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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')
)
}
const install = (Vue, vm) => {
initNetworkStatus()
bindNetworkStatusListener()
bindGlobalRequestInterceptor()
Vue.prototype.$u.http.setConfig({
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)
})
}
}
// 请求拦截部分,如配置,每次请求前都会执行
Vue.prototype.$u.http.interceptor.request = (config) => {
if (!refreshNetworkStatusSync()) {
showNoNetworkToast()
// 返回false可中断请求uView内置约定
return false
}
config.header = config.header || {}
const token = uni.getStorageSync('token')
config.header.Authorization = token
// config.header.Tenant-Id=1
// #ifdef H5
config.header.Authorization = 'Bearer ' + token
// #endif
// 可以对某个url进行特别处理此url参数为this.$u.get(url)中的url值
if (config.url == '/user/login') config.header.noToken = true
// 最后需要将config进行return
return config
}
// 响应拦截,如配置,每次请求结束都会执行本方法
Vue.prototype.$u.http.interceptor.response = (res) => {
return res
}
}
export default {
install
}