使用 React Hooks 和 fetch API 封装的简单的 HTTP 请求工具。
import qs from 'qs'
import { useCallback } from 'react'
// 请求配置接口
interface IRequestConfig extends RequestInit {
data?: Record<string, unknown> // 请求数据对象
token?: string // 认证令牌
}
const baseUrl = process.env.REACT_APP_BASE_URL // 根据项目环境匹配接口
let controller: AbortController // 请求控制器 用于取消请求
// 发送HTTP请求的函数
const Http = (url: string, { data, token, ...customerConfig }: IRequestConfig) => {
// 如果之前有正在进行的请求,则取消它
if (controller) {
controller.abort()
}
controller = new AbortController()
// 构建请求配置对象
const config: RequestInit = {
method: 'GET',
headers: {
'Content-Type': 'application/json',
Authorization: token ? `Bearer ${token}` : '',
},
signal: controller.signal,
...customerConfig,
}
// 处理GET请求的查询参数和其他请求方式的请求体
if (config.method?.toUpperCase() === 'GET') {
url += `?${qs.stringify(data)}`
} else {
config.body = data ? JSON.stringify(data) : ''
}
// 发送请求并处理响应
return window
.fetch(`${baseUrl}${url}`, config)
.then(async (response) => {
// 返回状态码按具体情况修改
if (response.status === 401) {
return Promise.reject('没权限')
}
const data = await response.json()
if (response.ok && data.code === 200) {
return Promise.resolve(data.data)
} else {
return Promise.reject(data)
}
})
.catch((error) => {
return Promise.reject(error)
})
}
// 自定义Hook,用于在组件中进行HTTP请求
export const useHttp = () => {
const token = '1111' // 动态获取token认证令牌
return useCallback(
(...[url, config]: Parameters<typeof Http>) => {
return Http(url, { token, ...config })
},
[token],
)
}
// 带超时的请求
const httpWithTimeout = (...[url, config]: Parameters<typeof Http>) => {
const timeoutPromise = (delay: number = 3000) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('请求超时')
}, delay)
})
}
return Promise.race([timeoutPromise(5000), Http(url, config)])
}