[网络] Axios 网络请求库讲解
![[网络] Axios 网络请求库讲解](https://cdn.hashnode.com/res/hashnode/image/upload/v1708319020998/7d7ba3b5-4159-47d5-8ebd-2e62678190b5.avif)
对于axios的使用,我已不陌生,但是想要进一步的了解一些细节,所以就打算写一篇博客,用于总结;这篇博客主要是axios和ts一起使用,并结合一些常见的业务场景来进行讲解
axios 实例的基础封装
基础的步骤如下:
创建一个
axios instance,配置其baseURL,有需要的话就配置一下代理为
axios instance添加拦截器,处理错误、请求、响应
axios 请求头注意事项
默认情况下,axios发起请求会将Conten-Type设置为json格式,所以我们如果想要发送其他格式的请求的话,需要在axios实例发起请求的第三个参数中配置headers,如下:
export const patchImport = async (payload: FormData) => {
const { data } = await test2Instance.post<any>(
"/enterprise/import",
payload,
{
headers: {
"Content-Type": "multipart/form-data" // 配置其他类型的请求
}
},
)
return data
}
axios 拦截器的注意事项
默认情况下,在后端返回数据经过axios的拦截器后,axios会将响应体数据默认再包裹一层data字段;所以我们可以在拦截器中直接返回data中的数据,减少层级,示例如下:
instance.interceptors.response.use(
(res: AxiosResponse) => {
return res.data
},
(err: AxiosError) => {
return Promise.reject(err)
}
)
这样写之后,你会发现axios返回的数据的类型检验上是有问题的;因为axios并不能自动推断拦截器所返回的数据类型,而是需要我们手动在axios实例请求中声明类型,例如:
/**
这里 instance post 请求的返回类型实际上是 AxiosResponse<Person>
即使你在拦截其中返回的是 res.data 而不是 res
*/
await instance.post<Person>
我们直接来看 axios对于其实例请求的类型声明:
request<T = any, R = AxiosResponse<T>> (config: AxiosRequestConfig): Promise<R>
可以看出,所有类型的请求都会返回一个Promise<R>类型,并且request的第一个泛型参数是T,而第二个泛型参数R如果不手动声明,那么默认就会包上一层AxiosResponse,多出来的那一层data就是这么来的
所以,我们可以不管第一个泛型参数,而是直接给第二个参数赋一个返回的数据类型,就可以使得axios的类型校验争取
但是要注意:这里只是改变了类型声明而已,axios并不会因为类型声明而改变其返回的数据的层级结构,我们必须要与axios响应拦截器中的return res.data结合使用才是完全正确的
axios 登录过期重定向到登录页面
这是一个很常见的业务场景,通常结合router的使用,让用户跳转到对应的界面就行了
首先我们需要判断响应状态码:
instance.interceptors.response.use(
(res: AxiosResponse) => {
// 响应状态码为 2xx 的时候会走这个函数
return res
},
(err: AxiosError) => {
// 响应状态码在 2xx 以外的会走这个函数
// 如果响应状态码为 401 未授权, 则导航到登录页
if(err.response.status === 401) {
// 执行导航重定向操作...
}
return Promise.reject(err)
}
)
然后vue和react的导航有些不同
vue的router是可以直接从声明router对象的文件中引入,并可以直接在.vue组件外直接使用的
而react的router是通过useRouter获取的,由于hook只能在组件或其他hook中使用,所以还必须多下载一个history包才可以
![[JS] fetch 不捕获 4xx](https://cdn.hashnode.com/res/hashnode/image/upload/v1752292253648/9db0ffc4-101a-41a9-9484-b3891c2d81b3.png)
![[Node] Mac m 芯片使用 node 14](https://cdn.hashnode.com/res/hashnode/image/upload/v1752243750001/cf2a586a-c5f8-488c-84a7-a3f7068f34b2.jpeg)
![[其他] WSL Interop](https://cdn.hashnode.com/res/hashnode/image/upload/v1752241086475/51441fc0-e5d9-4423-b009-ac9af9a51c04.jpeg)