Open sanlangguo opened 3 years ago
需求理解, 当此时接口请求失败时 如 Network Error 可能出现域名被封,连接不到服务器,这个时候重新获取备案域名列表
实现步骤
全局拦截 axios 处理 import axios from 'axios' import { config } from '@/api/config.js' import axiosRetry from 'axios-retry' import { getSpareDomains } from '@/api' // axios 公共变量 const axiosConf = { local: 'test-domain', timeout: 50000, headers: {} } / * * uat dev prod 域名不一致,可能调用多个服务, 分开写 DOMAIN_Conf_1,有逻辑可以共用 */ const DOMAIN_Conf_1 = { ...axiosConf, uat: 'uat1-com', production: 'prod1-com' } const DOMAIN_Conf_2 = { ...axiosConf, uat: 'uat2-com', production: prod2-com' } export const api_1 = axios.create({ baseURL: config.url_1, ...DOMAIN_Conf_1 }) export const api_2 = axios.create({ baseURL: config.url_2, ...DOMAIN_Conf_2 }) const services = [ api_1, api_2, ] services.forEach(service => { axiosRetry( service, { retries: 0 }, { retryCondition (error) { return error.code === 'ECONNABORTED' // Retry timed out requests } } ) // response interceptors service.interceptors.response.use( response => { if (response.status == 200) { return response.data } }, async (error) => { // 符合错误类型时,调用 if (error && error.message && error.message.includes('Network')) { const res = await getSpareDomains(error) return res } else { return Promise.reject(error) } } ) })
js 不能本机去 ping 域名是否可以使用 2. 如果通过接口去 ping 不能模拟本地的网络是否能访问 (例如上海联通不通,其他地方的联通是可以通的,所以只能本机轮训备用域名)
api/index.js // 测试数据 // const resObj = { // 'test-domain': 'test-domain-1, test-domain-2', // 'uat1-com': 'uat1-com-1, uat1-com-2', // 'prod1-com: prod1-com-1, prod1-com-2', // } import axios from 'axios' import { HTTPS } from '@/api/config.js' const env = process.env.VUE_APP_WEB // 公共业务域名接口 const API = axios.create({ baseURL: HTTPS.url, timeout: 50000, }) API.interceptors.response.use( response => { // eslint-disable-next-line if (response.status == 200) { return response.data } }, error => { return Promise.reject(error) } ) // update deposit account number export const getSpareDomains = async (error) => { // 防止多次请求备案域名 const domains = JSON.parse(window.sessionStorage.getItem('domains')) let url = error.config[env] if (domains) { url = await checkDomain(error, domains) } else { const res = await API.get('api/1/app/param/config/domain') if (res.code === 1 && res.data) { for (const key in res.data) { if (res.data[key]) { res.data[key] = res.data[key].replace(/\s+/g, '') res.data[key] = res.data[key].split(',') } } window.sessionStorage.setItem('domains', JSON.stringify(res.data)) url = await checkDomain(error, res.data) } } return url } const checkDomain = async function (error, data) { const checkName = error.config[env] let result = null // 返回响应值 for (const key in data) { if (key === checkName && data[key].length) { for (let i = 0; i < data[key].length; i++) { if (!result) { result = await retryHttps(error, data[key][i]) } else { return result } } } } return result } async function retryHttps (error, url) { error.config.baseURL = error.config.baseURL.replace(error.config.baseURL.split('/')[2], url) error.config.url = error.config.url.replace(error.config.url.split('/')[2], url) return axios.request(error.config).then(res => { return res.data }).catch(e => { return false }) }
需求背景动态域名切换--axios 请求失败时,切换当前域名,用新的域名请求
需求理解, 当此时接口请求失败时 如 Network Error 可能出现域名被封,连接不到服务器,这个时候重新获取备案域名列表
实现步骤