Я часто сталкиваюсь с аксиосами, когда учусь и делаю проекты.Проекты, которые я делал раньше, вообще были настроены с аксиосами, поэтому у меня всегда было общее впечатление.Недавно у меня появилась возможность самому вручную настроить аксиосы.Кстати, буду записывай и делись ~
Преимущества упаковки axios
Пакет преимуществ Axios является единым процессом, повышение эффективности и простоты обслуживания.
Вы можете использовать интерфейс запроса axios, как показано ниже.
axios.get('http://localhost:10086/user?ID=12345')
.then(response => {
//成功后的操作...
})
.catch(error => {
//失败后的操作...
});
Но когда запросов к интерфейсу больше и требований больше, пишите такой код в каждом месте проекта, где нужны запросы к интерфейсу, что будет генерировать много повторяющегося кода, снижать эффективность нашей разработки и увеличивать затраты на обслуживание.
Идеи упаковки
Нам нужно централизованно настроить axios за один раз и адаптировать конфигурацию к большинству сценариев нашего проекта. Мы можем создать файл js, создать новый экземпляр axios с настраиваемой конфигурацией, а затем выполнить базовую настройку экземпляра, добавить необходимую обработку перед запросом (обработка тела запроса), после запроса (обработка возвращаемого результата) и другие этапы. , Затем экспортируйте его для использования.
Приоритет конфигурации
Конфигурации объединяются в порядке приоритета. Порядок такой: вlib/defaults.js
Найдите значение по умолчанию библиотеки, а затем примерыdefaults
атрибут, наконец, запрошенныйconfig
параметр. (Таким образом, мы также можем обрабатывать некоторые специальные сценарии отдельно)
lib/defaults.js в файле библиотеки axios в папке node_modules.
Пользовательские значения по умолчанию для экземпляра
const instance = axios.create({
baseURL: 'https://api.example.com'
});
Запрашиваемые параметры конфигурации
axios({
method:'get',
url:'http://bit.ly/2mTM3nY',
responseType:'stream' }).then(function(response) { response.data.pipe(fs.createWriteStream('ada_lovelace.jpg')) });
конфигурация экземпляра axios
1. Определите некоторую общую конфигурацию
- setBaseUrl
BaseUrl обычно делится на несколько адресов, таких как производство, разработка и тестирование. Мы можем получить config.js для хранения. Если это vue или react, мы можем создать новый env и другие файлы для хранения. Следующий baseUrl использует реагировать на переменные среды.
- Установить время ожидания запроса тайм-аута
- Установите формат Content-Type запроса данных (есть application/x-www-form-urlencoded, multipart/form-data, application/json...) и т. д.
import axios from 'axios'
export const request = createAxiosInstance()
function createAxiosInstance () {
const instance = axios.create({
baseURL: process.env.REACT_APP_BASE_URL,
timeout: 5000,
headers: {
// 可定义统一的请求头部
post: {
'Content-Type': 'application/json'
}
...
}
})
return instance
}
2. Добавляем некоторые нужные нам операции перед запросом,
- Например, вам нужно добавить токен в заголовок запроса
- Пустая обработка параметров запроса
(В примере на рисунке ниже передается пустое имя и personId, что вызовет двусмысленность. Независимо от того, нужно ли получить значение параметра пустым или игнорировать эти параметры, некоторые серверные части будут выполнять некоторую обработку, но внешний интерфейс должен стараться избегать этого~)
- Включать эффект анимации загрузки каждый раз, когда запрашивает интерфейс и т.д.
// 添加请求拦截器(在发送请求之前做些什么)
instance.interceptors.request.use((config) => {
//可添加开启loading效果的函数
loading.open()
//token 存在就添加到请求头里
token && (config.headers.Authorization = token)
// 过滤请求参数中的 null undefined ''的函数
cleanObject()
return config
})
3. После возврата запроса добавьте операцию перехвата,
- Обработать возвращенные данные успешно
Например, данные, возвращаемые серверной частью, могут быть вложены во многие слои.Вы можете напрямую возвращать нужные вам данные, чтобы бизнес-код мог напрямую получать окончательные данные, не разбирая их каждый раз.
- Отчет об исключении после сбоя унифицированной обработки
Запрос интерфейса имеет как успех, так и неудачу.Если вы не хотите писать неудачный логический код каждый раз, когда вы пишете запрос интерфейса, и он почти всегда повторяется, то вы можете сосредоточиться на унифицированной обработке исключений для интерфейса здесь. Например, оценка кода состояния или кода, настроенного серверной частью, и отображение сообщения об ошибке, возвращенного серверной частью.
// 添加响应拦截器(对响应数据做点什么)
instance.interceptors.response.use((response) => {
//可添加关闭loading效果的函数
loading.close()
//解构出返回结果的数据
const res = response.data
//对自定义code码进行判断,将成功的数据返回出去
const validateStatus = /^(2|3)\d{2}$/ //code为2或3开头的视作请求成功
if (validateStatus.test(res.code)) {
return res.data //直接return出去我们需要的data
}
//判断失败的code码并作出提示等操作
if (res.code === 401) {
message.error(res.msg)
} else {
message.warning(res.msg)
}
return Promise.reject(res)
},
(error) => {
loading.close()
if (error.response.status === 401) {
message.error('token失效,请重新登录!')
removeStorageToken()
setTimeout(() => {
window.location.href = '/login'
}, 2000)
} else {
if (!window.navigator.onLine) {
message.warning('网络异常,请检查网络是否正常连接')
} else if (error.code === 'ECONNABORTED') {
message.warning('请求超时')
} else {
message.warning('服务器异常,请联系管理员')
}
}
return Promise.reject(error) // 将错误继续返回给到具体页面
}
)
Есть некоторая обработка ошибок, основанная на коде состояния HTTP и пользовательском коде.После того, как здесь выполнен перехват ошибок, нет необходимости обрабатывать сообщение об ошибке каждый раз, когда страница вызывает бизнес-интерфейс. Конечно, он должен быть настроен в соответствии с различными требованиями проекта.
Унифицированное управление методами интерфейса запросов
Как правило, мы будем писать все методы запроса интерфейса вместе для унифицированного управления, а также их легко найти и поддерживать при последующих изменениях.Мы можем создать новую папку (например, apiList) для управления запросами API и поместить в нее наши различные файлы запросов (здесь по функциям). Например, user.js хранит пользовательские запросы и так далее. Тогда страница может напрямую ссылаться на метод для вызовов интерфейса.
import { request } from '../axios'
// 获取用户信息
export function getUserInfo (userId) {
return request.get(`/sys/user/info/${userId}`)
}
Вы можете напрямую вызвать метод на компоненте или странице~
Наконец-то поставили про полный образец! Вы можете обратиться к ~
Этот пример конфигурации подходит для Vue или реагирует. Конечно, конфигурация каждого проекта будет немного отличаться. Небольшие партнеры должны изменять конфигурацию и расширяться в соответствии со своими собственными проектами ~
import axios from 'axios'
export const request = createAxiosInstance()
function createAxiosInstance () {
const instance = axios.create({
baseURL: process.env.REACT_APP_BASE_URL,
timeout: 5000,
headers: {
// 可定义统一的请求头部
post: {
'Content-Type': 'application/json'
}
...
}
})
// 添加请求拦截器(在发送请求之前做些什么)
instance.interceptors.request.use((config) => {
//可添加开启loading效果的函数
loading.open()
//token 存在就添加到请求头里
token && (config.headers.Authorization = token)
// 过滤请求参数中的 null undefined ''的函数
cleanObject()
return config
})
// 添加响应拦截器(对响应数据做点什么)
instance.interceptors.response.use((response) => {
//可添加关闭loading效果的函数
loading.close()
//解构出返回结果的数据
const res = response.data
//对自定义code码进行判断,将成功的数据返回出去
const validateStatus = /^(2|3)\d{2}$/ //code为2或3开头的视作请求成功
if (validateStatus.test(res.code)) {
return res.data
}
//判断失败的code码并作出提示等操作
if (res.code === 401) {
message.error(res.msg)
} else {
message.warning(res.msg)
}
return Promise.reject(res)
},
(error) => {
loading.close() //可添加关闭loading效果的函数
if (error.response.status === 401) {
message.error('token失效,请重新登录!')
removeStorageToken()
setTimeout(() => {
window.location.href = '/login'
}, 2000)
} else {
if (!window.navigator.onLine) {
message.warning('网络异常,请检查网络是否正常连接')
} else if (error.code === 'ECONNABORTED') {
message.warning('请求超时')
} else {
message.warning('服务器异常,请联系管理员')
}
}
return Promise.reject(error) // 将错误继续返回给到具体页面
}
)
return instance
}