兰 亭 墨 苑
期货 · 量化 · AI · 终身学习
首页
归档
编辑文章
标题 *
URL 别名 *
内容 *
(支持 Markdown 格式)
# Axios介绍 - 早期与主流浏览器环境中,Axios主要是对 XMLHttpRequest(XHR)的封装。 - 在非浏览器环境(如 Node.js),Axios使用自有的适配器,底层基于 Node 的 http/https 模块实现。 - 近几年,Axios也提供了基于 fetch 的适配器选项,但默认仍非 fetch;是否走 fetch 取决于所用适配器/版本与配置。 展开说明: - 适配器机制(adapters) - 浏览器适配器:封装 XHR,提供 Promise 接口、拦截器、请求/响应转换、超时、取消(早期基于 CancelToken,后期支持 AbortController)、CSRF 辅助等。 - Node 适配器:不使用 XHR/Fetch,而是用 http/https 构建请求,保持相同的 Axios API 语义。 - 自定义/实验性 fetch 适配器:某些版本或社区包可将底层改为 fetch(如 axios/axios v1.4+ 引入 fetch adapter 选项,或通过第三方适配器)。开启后由 fetch 驱动,但行为细节会尽量模拟 Axios 既有语义。 - 与原生 fetch 的差异点(为什么很多项目还用 Axios) - 拦截器体系(请求/响应统一处理) - 自动 JSON 序列化/解析与更一致的错误处理(非 2xx 会 reject) - 内置超时参数、重试/重定向策略可扩展 - 更好的旧浏览器兼容历史(在不支持 fetch 的环境中可工作) - 更丰富的请求取消与进度回调支持(基于 XHR 的 onUploadProgress/onDownloadProgress) - 当前实践建议 - 现代浏览器/Node 18+:优先考虑原生 fetch(搭配轻量封装处理拦截/重试/JSON/错误),减少依赖与体积。 - 需要拦截器、进度回调、统一跨端行为或要兼容旧环境时:Axios 依然合适;若想对齐平台标准,可尝试其 fetch 适配器或使用基于 fetch 的库(如 ky、ofetch)。 一句话回答: - Axios在浏览器里历来是“基于XHR的封装”,在Node里用http/https适配;它并非天然基于fetch,但现在可以切到fetch适配器,取决于你的配置与运行环境。 下面按“常用场景→示例代码→要点提示”的结构,快速覆盖 Axios 的主要用法。示例以浏览器与 Node 通用写法为主(Node 需先 npm i axios)。 一、基础请求 - GET ```js import axios from 'axios'; const res = await axios.get('https://api.example.com/users', { params: { page: 1, pageSize: 20 }, // 自动序列化为 ?page=1&pageSize=20 headers: { 'X-Client': 'demo' }, }); console.log(res.status, res.data); ``` - POST JSON ```js const res = await axios.post('https://api.example.com/users', { name: 'Alice', role: 'admin' }, // 自动设置 Content-Type: application/json { timeout: 5000 } ); ``` - PUT / PATCH / DELETE ```js await axios.put('/users/123', { name: 'Bob' }); await axios.patch('/users/123', { role: 'editor' }); await axios.delete('/users/123'); ``` 二、全局与实例配置 - 创建实例(推荐为不同后端/微服务各建一个) ```js const api = axios.create({ baseURL: 'https://api.example.com', timeout: 8000, headers: { 'X-App': 'myapp' }, withCredentials: true, // 跨域携带 Cookie(需服务端允许) }); ``` - 使用实例 ```js const res = await api.get('/users', { params: { page: 1 } }); ``` - 设置全局默认值(影响所有实例/默认 axios) ```js axios.defaults.timeout = 10000; axios.defaults.headers.common['X-Trace'] = 'on'; ``` 三、请求与响应拦截器 - 典型用途:统一加 token、日志、处理非 2xx 错误、自动刷新凭证 ```js const api = axios.create({ baseURL: '/api' }); api.interceptors.request.use((config) => { const token = localStorage.getItem('token'); if (token) config.headers.Authorization = `Bearer ${token}`; return config; }, (error) => Promise.reject(error)); api.interceptors.response.use((response) => { return response; // 可统一处理 data }, async (error) => { const { response, config } = error; if (response?.status === 401 && !config._retry) { config._retry = true; // 刷新 token 的示例 const newToken = await refreshToken(); localStorage.setItem('token', newToken); config.headers.Authorization = `Bearer ${newToken}`; return api(config); // 重试原请求 } return Promise.reject(error); }); ``` 四、并发请求与聚合 ```js const [usersRes, postsRes] = await Promise.all([ axios.get('/api/users'), axios.get('/api/posts'), ]); console.log(usersRes.data, postsRes.data); ``` 五、查询参数与序列化 - 基本 params 会自动序列化 - 复杂对象/数组可使用 paramsSerializer ```js import qs from 'qs'; await axios.get('/search', { params: { tags: ['js', 'web'], range: { from: 1, to: 10 } }, paramsSerializer: (params) => qs.stringify(params, { arrayFormat: 'repeat' }), }); // => /search?tags=js&tags=web&range%5Bfrom%5D=1&range%5Bto%5D=10 ``` 六、表单与文件上传 - application/x-www-form-urlencoded ```js import qs from 'qs'; await axios.post('/login', qs.stringify({ username: 'a', password: 'b' }), { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } } ); ``` - multipart/form-data(文件上传,支持进度) ```js const form = new FormData(); form.append('file', fileInput.files[0]); form.append('desc', 'avatar'); await axios.post('/upload', form, { headers: { 'Content-Type': 'multipart/form-data' }, onUploadProgress: (e) => { const percent = Math.round((e.loaded * 100) / (e.total ?? e.loaded)); console.log('upload', percent + '%'); }, }); ``` 七、下载文件与进度 ```js const res = await axios.get('/report.pdf', { responseType: 'blob', onDownloadProgress: (e) => { const percent = Math.round((e.loaded * 100) / (e.total ?? e.loaded)); console.log('download', percent + '%'); }, }); // 浏览器保存 const url = URL.createObjectURL(res.data); const a = document.createElement('a'); a.href = url; a.download = 'report.pdf'; a.click(); URL.revokeObjectURL(url); ``` 八、超时与取消请求 - 超时 ```js await axios.get('/slow', { timeout: 3000 }); ``` - 取消(AbortController,Axios v1+) ```js const controller = new AbortController(); const p = axios.get('/data', { signal: controller.signal }); setTimeout(() => controller.abort(), 1000); await p.catch(err => console.log('aborted?', axios.isCancel(err))); ``` 九、错误处理与类型判断 ```js try { const res = await axios.get('/api'); console.log(res.data); } catch (err) { if (axios.isAxiosError(err)) { console.log('status', err.response?.status); console.log('data', err.response?.data); console.log('code', err.code); // 'ECONNABORTED' 等 } else { console.error('unexpected', err); } } ``` 十、拦截器中的重试与退避(简单示例) ```js const api = axios.create(); api.interceptors.response.use(undefined, async (error) => { const config = error.config; const retry = (config.__retryCount ?? 0); const shouldRetry = (!error.response || error.response.status >= 500) && retry < 3; if (!shouldRetry) throw error; config.__retryCount = retry + 1; const delay = 300 * 2 ** retry; // 指数退避 await new Promise(r => setTimeout(r, delay)); return api(config); }); ``` 十一、与 fetch 的互操作(可选:fetch 适配器) - 让 Axios 基于 fetch 运行(行为会略有差异) ```js import axios from 'axios'; import { fetchAdapter } from '@vespaiach/axios-fetch-adapter'; const api = axios.create({ adapter: fetchAdapter }); ``` 十二、TypeScript 提示与类型 ```ts import axios, { AxiosResponse } from 'axios'; type User = { id: number; name: string }; const res: AxiosResponse<User[]> = await axios.get('/users'); res.data.forEach(u => console.log(u.id)); ``` 十三、常见最佳实践 - 为每个后端定义 axios 实例,集中配置拦截与重试策略。 - 在响应拦截器中统一只返回 response.data,简化调用层。 - 上传/下载大文件使用 onUploadProgress/onDownloadProgress,并设定合理的 timeout 与最大内容长度限制(maxContentLength、maxBodyLength 在 Node 环境)。 - 对幂等请求(GET/PUT)才做自动重试;POST 等非幂等操作需配合幂等键或谨慎处理。 - 跨端项目(浏览器+Node)注意差异:Cookie、CORS、代理、HTTP/HTTPS Agent、证书校验等在 Node 端另有配置点。
配图 (可多选)
选择新图片文件或拖拽到此处
标签
更新文章
删除文章