axios API 参考详解:实例、请求类型、错误体系与工具函数的完整手册
【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios
本文基于 axios 仓库的 API 参考文档,系统梳理当前版本中所有可用的公共 API:axios实例、Axios核心类、TypeScript 泛型请求类型、错误类体系(AxiosError/CanceledError)、请求头工具类AxiosHeaders,以及toFormData、getAdapter、mergeConfig等函数与HttpStatusCode常量。每个 API 均给出类型签名、用法示例,并结合仓库源码说明其底层实现位置与行为细节,帮助你既能正确调用这些 API,也能理解它们背后的设计。
API 总览与导出入口
axios 遵循语义化版本承诺:在不发布主版本变更的情况下,以下所有函数和类将保持稳定不变。所有 API 既可以从包入口以命名导入的方式获取,也可以作为axios默认导出对象的静态属性访问。
包入口 index.js 将默认导出解包为命名导出,完整导出列表如下:
| 导出 | 类型 | 说明 |
|---|---|---|
axios(默认导出)、create | 函数 | 实例工厂函数 |
Axios | 类 | 发起 HTTP 请求的核心类 |
AxiosError | 类 | 请求失败时抛出的错误类 |
AxiosHeaders | 类 | HTTP 请求头管理工具类 |
CanceledError、Cancel | 类 | 请求取消错误(Cancel为向后兼容别名) |
CancelToken | 类 | 已废弃,请改用AbortController |
isCancel、isAxiosError | 函数 | 错误类型守卫 |
all、spread | 函数 | Promise 辅助函数(all已废弃) |
toFormData、formToJSON | 函数 | 对象与FormData互转 |
getAdapter、mergeConfig | 函数 | 适配器解析与配置合并 |
HttpStatusCode | 常量对象 | HTTP 状态码命名常量 |
VERSION | 字符串 | 当前版本号 |
这些静态属性的挂载逻辑集中在 lib/axios.js 中,例如axios.AxiosError = AxiosError、axios.AxiosHeaders = AxiosHeaders、axios.getAdapter = adapters.getAdapter,因此import axios from 'axios'后访问axios.xxx与命名导入是等价的。
实例:axios与create
axios实例是你发起 HTTP 请求的主要对象,它是一个创建Axios类新实例的工厂函数。实例提供了get、post、put、delete、patch、query以及对应的xxxForm请求方法,详见仓库文档中的请求别名章节。
从源码看,默认实例由 lib/axios.js 中的createInstance函数创建:
function createInstance(defaultConfig) { const context = new Axios(defaultConfig); const instance = bind(Axios.prototype.request, context); // Copy axios.prototype to instance utils.extend(instance, Axios.prototype, context, { allOwnKeys: true }); // Copy context to instance utils.extend(instance, context, null, { allOwnKeys: true }); // Factory for creating new instances instance.create = function create(instanceConfig) { return createInstance(mergeConfig(defaultConfig, instanceConfig)); }; return instance; } // Create the default instance to be exported const axios = createInstance(defaults);这段实现揭示了三个关键事实:
- 你直接调用的
axios(config)、axios.get(url)最终都汇聚到Axios.prototype.request(通过bind绑定到内部 context 上); - 实例同时拷贝了
Axios.prototype的方法与 context 的属性(defaults、interceptors等),所以拦截器、默认配置在实例上都是可访问的; instance.create(instanceConfig)会以mergeConfig(defaultConfig, instanceConfig)为基础派生新实例——这是"基于现有实例再定制"的标准做法,新实例的默认配置是父实例默认配置与增量配置的合并结果。
默认实例的初始配置来自 lib/defaults/index.js。
TypeScript 请求类型
公共请求类型使用不同的泛型分别表示请求数据和查询参数:
AxiosRequestConfig<D = any, P = any> RawAxiosRequestConfig<D = any, P = any> InternalAxiosRequestConfig<D = any, P = any> AxiosDefaults<D = any, P = any> CreateAxiosDefaults<D = any, P = any> AxiosResponse<T = any, D = any, H = {}, P = any> AxiosPromise<T = any, D = any, P = any> AxiosError<T = unknown, D = any, P = any> CanceledError<T, D = any, P = any>其中D是请求体类型,P是查询参数类型。AxiosResponse、AxiosPromise、错误、默认配置、可调用实例、请求别名、适配器和mergeConfig()都会在请求配置中保留这两种类型;自定义参数序列化器会接收同一个P。
请求方法使用<T, R, D, P>的泛型顺序,将P添加在最后,因此现有的显式泛型参数保持兼容。未提供自定义响应类型R时,默认AxiosResponse会在response.config中保留D和P;显式提供的R仍然控制最终返回值。为保持向后兼容,请求数据和参数泛型均默认为any。类型声明本身位于仓库根目录的 index.d.ts,需要严格类型校验时可对照该文件。
类:Axios
Axios类是发起 HTTP 请求的核心类,实现位于 lib/core/Axios.js。
constructor
创建一个新的Axios实例,构造函数接受一个可选的配置对象作为参数:
constructor(instanceConfig?: AxiosRequestConfig);源码实现非常简洁(lib/core/Axios.js#L22-L29):
class Axios { constructor(instanceConfig) { this.defaults = instanceConfig || {}; this.interceptors = { request: new InterceptorManager(), response: new InterceptorManager(), }; } // ... }即每个实例只持有两样东西:默认配置defaults和一对拦截器管理器。Axios类还被显式导出(axios.Axios = Axios),目的是允许类继承——你可以class MyClient extends Axios扩展自定义客户端。
request
处理请求调用和响应解析,是发起 HTTP 请求的核心方法:
request<T, R, D, P>(config: AxiosRequestConfig<D, P>): Promise<R>;_request内部流程(lib/core/Axios.js#L82-L258)可以概括为:
- 支持 fetch 风格的
axios('url'[, config])调用:字符串参数会被包装为{ url }; - 通过
mergeConfig(this.defaults, config)合并实例默认配置与请求级配置,请求级配置优先; - 校验
transitional选项与paramsSerializer(允许直接传函数,会自动包装为{ serialize }); - 解析
method(缺省为get)并压平按方法分组的请求头(headers.common与headers[config.method]),最终生成AxiosHeaders实例; - 组装拦截器链:请求拦截器按注册顺序串联(
runWhen返回false的拦截器会被跳过),中间插入dispatchRequest,再串联响应拦截器,返回 Promise。
Axios类还提供getUri(config)方法,它只做mergeConfig→buildFullPath→buildURL的组合,用于在不发送请求的情况下生成完整 URL(含查询参数),适合生成跳转链接或调试。
方法别名(get/post等)在类文件底部统一生成(lib/core/Axios.js#L267-L306):
- 无数据方法
delete、get、head、options签名为method(url, config); - 有数据方法
post、put、patch、query签名为method(url, data, config),并额外生成postForm、putForm、patchForm快捷方法(自动设置Content-Type: multipart/form-data)。
错误体系:AxiosError与CanceledError
AxiosError
AxiosError类是 HTTP 请求失败时抛出的错误类,继承自Error并添加了额外属性,实现位于 lib/core/AxiosError.js。
constructor
constructor(message?: string, code?: string, config?: InternalAxiosRequestConfig<D, P>, request?: any, response?: AxiosResponse<T, D, {}, P>);构造函数会将response.status同步到error.status,并把isAxiosError = true标记写入实例——这正是isAxiosError类型守卫的判定依据。
properties
// 配置实例。 config?: InternalAxiosRequestConfig<D, P>; // 错误代码。 code?: string; // 请求实例。 request?: any; // 响应实例。 response?: AxiosResponse<T, D, {}, P>; // 表示该错误是否为 AxiosError 的布尔值。 isAxiosError: boolean; // 错误状态码。 status?: number; // 将错误转换为 JSON 对象的辅助方法。 toJSON: () => object; // 错误原因。 cause?: Error;源码中还有两点值得注意的实现细节:
- 除构造函数外,类上还有一个静态方法
AxiosError.from(error, code, config, request, response, customProps)(lib/core/AxiosError.js#L99-L131),用于把任意原生错误(如 Node 的连接错误)包装成AxiosError并保留cause链; toJSON()支持可选的敏感字段脱敏:当请求配置中带有redact键值数组时,序列化出的config快照中对应字段(不区分大小写、任意深度)会被替换为[REDACTED ****]。
类上还定义了一组常见错误码常量,供与error.code比较:ECONNABORTED、ETIMEDOUT、ECONNREFUSED、ERR_NETWORK、ERR_CANCELED、ERR_BAD_RESPONSE、ERR_BAD_REQUEST、ERR_NOT_SUPPORT、ERR_FR_TOO_MANY_REDIRECTS、ERR_INVALID_URL等(lib/core/AxiosError.js#L204-L217)。
isAxiosError
检查某个错误是否为AxiosError的函数。在catch块中使用此函数,可安全访问 axios 特有的错误属性,如error.response和error.config:
isAxiosError(value: any): value is AxiosError;import axios from 'axios'; try { await axios.get('/api/resource'); } catch (error) { if (axios.isAxiosError(error)) { // error.response、error.config、error.code 均可使用 console.error('HTTP error', error.response?.status, error.message); } else { // 非 axios 错误(例如编程错误) throw error; } }实现只有一行(lib/helpers/isAxiosError.js):判断对象上isAxiosError === true,对应单元测试见 tests/unit/helpers/isAxiosError.test.js。
CanceledError
CanceledError类是 HTTP 请求被取消时抛出的错误类,继承自AxiosError:
constructor(message?: string, config?: InternalAxiosRequestConfig<D, P>, request?: any); __CANCEL__?: boolean;源码(lib/cancel/CanceledError.js)中它固定使用错误码AxiosError.ERR_CANCELED,并打上__CANCEL__ = true标记:
class CanceledError extends AxiosError { constructor(message, config, request) { super(message == null ? 'canceled' : message, AxiosError.ERR_CANCELED, config, request); this.name = 'CanceledError'; this.__CANCEL__ = true; } }Cancel
Cancel是CanceledError的别名,为向后兼容而保留导出,将在未来版本中移除:
Cancel: typeof CanceledError;在 lib/axios.js#L63 中可见其定义:axios.Cancel = axios.CanceledError。
isCancel
检查某个错误是否为CanceledError的函数,可用于区分主动取消和意外错误:
isCancel<T = any, D = any, P = any>(value: any): value is CanceledError<T, D, P>;import axios from 'axios'; const controller = new AbortController(); axios.get('/api/data', { signal: controller.signal }).catch((error) => { if (axios.isCancel(error)) { console.log('Request was cancelled:', error.message); } else { console.error('Unexpected error:', error); } }); controller.abort('User navigated away');实现同样极简(lib/cancel/isCancel.js):检查value.__CANCEL__标记,与上面CanceledError构造函数中的赋值相互印证。
类:CancelToken(已废弃)
CancelToken类基于tc39/proposal-cancelable-promises提案,用于创建可取消 HTTP 请求的令牌。该类现已废弃,推荐使用AbortControllerAPI。
从 0.22.0 版本起,CancelToken类已废弃,将在未来版本中移除。建议改用AbortControllerAPI。
该类主要为了向后兼容而保留导出,未来将被移除。我们强烈不建议在新项目中使用;下面的旧版互操作辅助方法仅为已有代码列出。这些旧版方法仍为现有集成提供类型:
subscribe(listener: (cancel: Cancel | any) => void): void; unsubscribe(listener: (cancel: Cancel | any) => void): void; toAbortSignal(): AbortSignal;其中toAbortSignal()是把旧CancelToken桥接到新AbortController世界的关键方法:它内部创建一个AbortController,把abort回调订阅到 token 的取消信号上,使两套取消机制可以互通(实现见 lib/cancel/CancelToken.js#L105-L117)。
类:AxiosHeaders
AxiosHeaders类是用于管理 HTTP 请求头的工具类,提供添加、删除和获取请求头等操作方法,实现位于 lib/core/AxiosHeaders.js。请求管线中所有配置头(实例默认头、方法头、请求头)最终都会通过AxiosHeaders.concat归一化为该类的实例,因此了解它对调试请求行为很有帮助。
此处仅列出主要方法,完整方法列表请参阅类型声明文件 index.d.ts。
constructor
创建一个新的AxiosHeaders实例,构造函数接受一个可选的请求头对象作为参数:
constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);set
向请求头对象添加一个请求头。空字符串或仅包含空白字符的请求头名称会被忽略。
set(headerName?: string, value?: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher): AxiosHeaders; set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean): AxiosHeaders; set(headers?: Iterable<[string, AxiosHeaderValue]>, rewrite?: boolean): AxiosHeaders;从源码看(lib/core/AxiosHeaders.js#L203-L257),set支持三种输入形态:单个name/value对、普通对象或AxiosHeaders实例、以及可迭代的键值对(重复键会被合并为数组);传入无法识别为合法头名的长字符串时,会按原始头块文本解析(parseHeaders)。rewrite为true时强制覆盖已有同名头。
get
从请求头对象获取一个请求头:
get(headerName: string, parser: typeof AxiosHeaders.parseParameters): AxiosHeaderParameters; get(headerName: string, parser: RegExp): RegExpExecArray | null; get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue;传入AxiosHeaders.parseParameters可将规范化的 HTTP 参数解析为安全的、原型为 null 的映射:
const headers = new AxiosHeaders({ "Content-Type": 'multipart/form-data; boundary="a,b"', }); console.log({ ...headers.get("Content-Type", AxiosHeaders.parseParameters), }); // { boundary: "a,b" }参数名称不区分大小写。解析器会移除带引号字符串的定界引号,解码转义的引号和反斜杠,保留带引号值中的逗号和分号,并且只移除不带引号值两侧的 RFC 可选空白。它会忽略__proto__、constructor和prototype。get(name, true)仍是旧版分词器。
这一行为在 lib/core/AxiosHeaders.js#L92-L149 的parseParameters函数中实现:字符级状态机处理引号与转义,parameterNameRE白名单校验参数名,并在归一化后显式过滤原型污染键名。而get(name, true)走的是更早期的parseTokens(正则分词)。
has
检查请求头对象中是否存在某个请求头:
has(header: string, matcher?: AxiosHeaderMatcher): boolean;delete
从请求头对象移除一个请求头:
delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;clear
从请求头对象移除所有请求头:
clear(matcher?: AxiosHeaderMatcher): boolean;matcher可以是字符串(子串匹配)、正则或函数,delete/clear都会按该条件选择性移除,返回值表示是否发生了删除。
normalize
规范化请求头对象:
normalize(format: boolean): AxiosHeaders;format为true时把头名格式化为首字母大写驼峰(如content-type→Content-Type),否则仅去除首尾空白;同时合并大小写不同的重复键。
concat
合并多个请求头对象:
concat(...targets: Array<AxiosHeaders | RawAxiosHeaders | string | undefined | null>): AxiosHeaders;静态版本AxiosHeaders.concat(first, ...targets)会基于first构造新实例,再依次set各目标,因此原对象不被修改。
toJSON
将请求头对象转换为 JSON 对象:
toJSON(asStrings: true): Record<string, string>; toJSON(asStrings?: false): Record<string, string | string[]>;asStrings为true时数组值会用', '连接成字符串;返回对象使用 null 原型创建,可避免原型污染风险。
toString
将请求头返回为不含 CRLF 的 HTTP 请求头块,每行一个name: value键值对:
toString(): string;此外,类通过AxiosHeaders.accessor为Content-Type、Content-Length、Accept、Accept-Encoding、User-Agent、Authorization六个常用头生成了getContentLength()/setContentLength()之类的驼峰访问器,日常代码里可以直接headers.getContentType()。
函数:Promise 辅助与表单工具
all(已废弃)
all函数接受一组 Promise 并返回一个在所有 Promise 都完成后才完成的单一 Promise,现已废弃,推荐使用Promise.all方法。
从 0.22.0 版本起,all函数已废弃,将在未来版本中移除。建议改用Promise.all方法。当前实现就是Promise.all的薄封装(lib/axios.js#L66-L68):
axios.all = function all(promises) { return Promise.all(promises); };spread
spread函数可将一个参数数组展开为函数调用的多个参数,在你需要将数组参数传递给接收多个参数的函数时非常实用:
spread<T, R>(callback: (...args: T[]) => R): (array: T[]) => R;实现见 lib/helpers/spread.js:
export default function spread(callback) { return function wrap(arr) { return callback.apply(null, arr); }; }典型用法:axios.all([p1, p2]).then(axios.spread(([user, repos]) => { /* ... */ }))(all废弃后等价于Promise.all+spread)。
toFormData
将普通 JavaScript 对象(包括嵌套对象)转换为FormData实例,在需要从对象中以编程方式构建 multipart 表单数据时非常实用:
toFormData(sourceObj: object, formData?: FormData, options?: FormSerializerOptions): FormData;import { toFormData } from 'axios'; const data = { name: 'Jay', avatar: fileBlob }; const form = toFormData(data); // form 现在是一个可直接发送的 FormData 实例 await axios.post('/api/users', form);第二个参数允许把转换结果追加进已存在的FormData;第三个参数FormSerializerOptions可控制可见性、深度限制(depth)、日期/数组/访客值格式化等行为,完整选项见 index.d.ts。嵌套深度超过上限会抛出AxiosError.ERR_FORM_DATA_DEPTH_EXCEEDED。
formToJSON
将FormData实例转换回普通 JavaScript 对象,在需要以结构化格式读取表单数据时非常实用:
formToJSON(form: FormData): object;import { formToJSON } from 'axios'; const form = new FormData(); form.append('user-name', 'johndoe'); form.append('user.name', 'john'); const obj = formToJSON(form); console.log(obj); // { "user-name": "johndoe", user: { name: "john" } }只有点号和方括号表示法具有结构含义:.、[和]会分隔路径,而-、空格、+、*和&会保留在字面键中。foo.bar和foo[bar]会创建嵌套对象,foo[]会创建数组。
这一语义由 lib/helpers/formDataToJSON.js 中的parsePropPath正则(/[^.[\]]+|\[([^.[\]]*)]/g)实现。另外,通过axios.formToJSON调用时还支持直接传入 HTML 表单元素,入口会自动执行new FormData(form)(lib/axios.js#L80)。
函数:适配器与配置合并
getAdapter
通过名称或名称数组解析并返回一个适配器函数。axios 在内部使用此函数为当前环境选择最合适的适配器:
getAdapter(adapters: string | string[]): AxiosAdapter;import { getAdapter } from 'axios'; // 显式获取 fetch 适配器 const fetchAdapter = getAdapter('fetch'); // 按优先级列表获取最合适的适配器 const adapter = getAdapter(['fetch', 'xhr', 'http']);实现位于 lib/adapters/adapters.js。内置适配器只有三个(knownAdapters):http(Node.js)、xhr(浏览器 XMLHttpRequest)、fetch(fetch API)。函数按列表顺序逐个尝试,第一个在当前环境可用的适配器胜出;全部不可用时会抛出带ERR_NOT_SUPPORT错误码的AxiosError,错误信息中会列出每个候选被拒绝的原因("not supported by the environment" 或 "not available in the build")。也可以直接传入适配器函数而非名称。各适配器的实现分别位于 lib/adapters/http.js、lib/adapters/xhr.js、lib/adapters/fetch.js,其选择策略详见仓库文档的适配器章节。
mergeConfig
合并两个 axios 配置对象,使用与 axios 内部合并默认配置和请求级选项相同的深度合并策略。后者的值优先级更高:
mergeConfig<D = any, P = any>( config1: AxiosRequestConfig<D, P>, config2: AxiosRequestConfig<D, P> ): AxiosRequestConfig<D, P>;import { mergeConfig } from 'axios'; const base = { baseURL: 'https://api.example.com', timeout: 5000 }; const override = { timeout: 10000, headers: { 'X-Custom': 'value' } }; const merged = mergeConfig(base, override); // { baseURL: "https://api.example.com", timeout: 10000, headers: { "X-Custom": "value" } }从源码(lib/core/mergeConfig.js)可以看出,它并非简单深拷贝:合并策略按属性类别分派——method、data、url等标量类属性直接取config2的值;headers走AxiosHeaders归一化后合并(区分大小写无关);baseURL、transformRequest等走"config2 优先、否则回退 config1"的策略;纯对象属性则递归深合并。合并结果使用 null 原型对象构造,避免下游读取config.auth等属性时继承被污染的原型值。请求管线中Axios.prototype._request的第一步就是调用它(lib/core/Axios.js#L92),所以对外暴露的mergeConfig与内部行为完全一致,可用于在自定义实例工厂中精确复现 axios 的合并规则。
常量:HttpStatusCode
包含 HTTP 状态码命名常量的对象,可用于编写更具可读性的条件判断,避免直接使用数字字面量,实现位于 lib/helpers/HttpStatusCode.js:
import axios, { HttpStatusCode } from 'axios'; try { const response = await axios.get('/api/resource'); } catch (error) { if (axios.isAxiosError(error)) { if (error.response?.status === HttpStatusCode.NotFound) { console.error('Resource not found'); } else if (error.response?.status === HttpStatusCode.Unauthorized) { console.error('Authentication required'); } } }该常量对象覆盖了 1xx 到 5xx 的常用状态码(Ok: 200、NoContent: 204、NotFound: 404、TooManyRequests: 429、InternalServerError: 500等)。值得注意的是,源码在末尾还做了一次反向映射(lib/helpers/HttpStatusCode.js#L82-L86):数字键映射回名称字符串,即HttpStatusCode[404]得到'NotFound',适合在日志中把状态码转成人类可读文案。此外PayloadTooLarge、UnprocessableEntity已被标注废弃,分别应使用ContentTooLarge、UnprocessableContent。
其他:VERSION
axios.VERSION是axios包的当前版本号字符串,随每次发布更新。源码中它来自构建时生成的数据模块(lib/axios.js#L12:import { VERSION } from './env/data.js'),因此打包产物中的版本号与发布的 npm 包版本保持一致,可用于运行时日志或按版本做特性开关判断。
小结
axios 的公共 API 面可以归纳为三层:
- 请求层:
axios实例与Axios类,通过request方法加拦截器链完成请求派发,create支持派生实例; - 错误层:
AxiosError(含ERR_*错误码与toJSON脱敏)、CanceledError与isCancel/isAxiosError两个类型守卫,配合AbortController取代已废弃的CancelToken; - 工具层:
AxiosHeaders管理请求头,toFormData/formToJSON处理表单互转,getAdapter/mergeConfig暴露了内部适配器解析与配置合并逻辑,HttpStatusCode与VERSION提供可读性常量。
所有 API 的语义以当前仓库的 index.d.ts 类型声明为准,行为实现以lib/下对应源码为准,测试用例集中在 tests/unit 目录,可用于验证各 API 的边界行为。
【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考