Видел в интернете много народных туториалов по упаковке Axios, но есть более-менее неподходящие моменты.Вот рекомендую свои наработки.
Перехватчик не возвращает данные, но все равно возвращает объект AxiosResponse
Все статьи в Интернете позволяют использовать перехватчик для прямого возврата данных, что на самом деле очень неуместно, что затруднит вам расширение последующих функций.
не рекомендуемая практика
import Axios from 'axios'
const client = Axios.create({
// 你的配置
})
client.interceptors.response.use(response => {
// 网上的做法都是让你直接返回数据
// 这导致后续的一些功能难以支持
return response.data
})
export default client
Рекомендуемая практика
Рекомендуется использовать функции вместо перехватчиков
import Axios, { AxiosRequestConfig } from 'axios'
const client = Axios.create({
// 你的配置
})
export async function request(url: string, config?: AxiosRequestConfig) {
const response = await client.request({ url, ...config })
const result = response.data
// 你的业务判断逻辑
return result
}
export default client
Некоторые люди могут сказать, что сейчас это слишком хлопотно, пожалуйста, подождите немного и продолжайте смотреть вниз.
Добавьте расширения к вашему запросу
Часто наш процесс разработки выглядит так:
发送请求 => 拿到数据 => 渲染内容
Но, к сожалению, это только идеальная ситуация, в некоторых особых случаях все равно нужно обрабатывать исключения или дополнительную поддержку, например:
- Когда запрос терпит неудачу, я надеюсь, что смогу автоматически повторить попытку более 3 раз, прежде чем произойдет сбой.
- В пейджинговых данных, когда выдается новый запрос, предыдущий запрос автоматически прерывается.
- Когда третья сторона предоставляет интерфейс jsonp, и вы можете использовать только статические страницы (ps: Axios не поддерживает jsonp)
- Более
При отправке вышеуказанных сценариев вы можете только писать код для их поддержки в автоматическом режиме, но если вы не перехватываете ответы Axios, вы можете использовать решения, предоставленные сообществом открытого исходного кода.
Повторить запрос в службу поддержки
Установитьaxios-retry, что позволяет вашему Axios поддерживать автоматический повтор
import Axios, { AxiosRequestConfig } from 'axios'
import axiosRetry from 'axios-retry'
const client = Axios.create({
// 你的配置
})
// 安装 retry 插件
// 当请求失败后,自动重新请求,只有3次失败后才真正失败
axiosRetry(client, { retries: 3 })
export async function request(url: string, config?: AxiosRequestConfig) {
const response = await client.request({ url, ...config })
const result = response.data
// 你的业务判断逻辑
return result
}
// 只有3次失败后才真正失败
const data = request('http://example.com/test')
PS: плагин axios-retry поддерживает настройку одного запроса
Поддержка jsonp-запроса
Установитьaxios-jsonp, может заставить ваш Axios поддерживать функцию jsonp.
import Axios, { AxiosRequestConfig } from 'axios'
import jsonpAdapter from 'axios-jsonp'
const client = Axios.create({
// 你的配置
})
export async function request(url: string, config?: AxiosRequestConfig) {
const response = await client.request({ url, ...config })
const result = response.data
// 你的业务判断逻辑
return result
}
export function jsonp(url: string, config?: AxiosRequestConfig) {
return request(url, { ...config, adapter: jsonpAdapter })
}
// 你现在可以发送 jsonp 的请求了
const data = jsonp('http://example.com/test-jsonp')
Поддержка версий URI
Любой, у кого есть опыт разработки веб-API, столкнется с проблемой: если в API произошли серьезные изменения, как обеспечить доступность старой версии и выпустить новый API?
Эта ситуация не редкость в сценариях разработки на стороне сервера, особенно для общедоступных API, таких как Douban API (несуществующий).
Текущий мейнстрим поддерживает 3 типа контроля версий:
тип | описывать |
---|---|
URI Versioning | Версия будет передана в URI запроса (по умолчанию) |
Header Versioning | Пользовательский заголовок запроса будет указывать версию |
Media Type Versioning | В заголовке Accept запроса будет указана версия |
Версии URIотносится к версии, переданной в URI запроса, например.https://example.com/v1/route
иhttps://example.com/v2/route
.
import Axios, { AxiosRequestConfig } from 'axios'
const client = Axios.create({
// 你的配置
})
client.interceptors.request.use(config => {
// 最简单的方案
config.url = config.url.replace('{version}', 'v1')
return config
})
// GET /api/v1/users
request('/api/{version}/users')
Режим заголовка и типа носителя, вы можете обратиться к следующим статьям, чтобы достичь
сохраняйте уникальные запросы
На странице фоновой таблицы, которая поддерживает перелистывание страниц, пользователь нажимает кнопку перелистывания страниц и запрашивает ожидание ответа, но когда пользователь нажимает поиск в это время, данные необходимо получить снова. :
- Сначала возвращается запрос на перелистывание страниц, возвращаются данные поиска, а отображение данных нормальное.
- Сначала возвращаются данные поиска, возвращаются данные страницы, и данные отображаются неправильно (обычно в сценариях балансировки нагрузки).
С этой целью вы хотите иметь возможность автоматически отменить последний запрос, поэтому вы видели запрос на отмену Axios, но его нужно использовать во многих местах, поэтому вы можете инкапсулировать эту функцию в независимую функцию.
import Axios from 'axios'
const CancelToken = Axios.CancelToken
export function withCancelToken(fetcher) {
let abort
function send(data, config) {
cancel() // 主动取消
const cancelToken = new CancelToken(cancel => (abort = cancel))
return fetcher(data, { ...config, cancelToken })
}
function cancel(message = 'abort') {
if (abort) {
abort(message)
abort = null
}
}
return [send, cancel]
}
использовать
function getUser(id: string, config?: AxiosRequestConfig) {
return request(`api/user/${id}`, config)
}
// 包装请求函数
const [fetchUser, abortRequest] = withCancelToken(getUser)
// 发送请求
// 如果上一次请求还没回来,会被自动取消
fetchUser('1000')
// 通常不需要主动调用
// 但可以在组件销毁的生命周期中调用
abortRequest()
Таким образом, когда автоматическая отмена не требуется, исходную функцию можно использовать напрямую, и это не повлияет на использование исходной функции.
послесловие
Инкапсуляция Axios на самом деле имеет много вещей, таких как глобальная обработка ошибок (то же самое не может повлиять на обычные запросы) и т. д. Инкапсуляция не должна просто использовать перехватчики для прямого возврата данных.
Кроме того, модуль запроса должен оставаться независимым, и его рекомендуется расширять.AxiosRequestConfig
Или сделать из них независимые функции и предоставить их для внешних вызовов, что удобно сделать независимым HTTP-модулем.