
axios AxiosHeaders 方法全集set/get/has/delete/normalize/concat 的完整指南【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios本文基于 axios 官方文档 Header methods 及配套源码系统讲解AxiosHeaders类提供的一组请求头操作方法构造函数、set、get、has、delete、clear、normalize、concat、toJSON、toString、from以及setContentType等快捷方法。读完后你将理解每个方法的重载签名、rewrite/matcher/parser三类选项参数的精确语义并能结合 源码实现 判断这些方法在请求管线中的真实调用时机。AxiosHeaders 在请求管线中的位置AxiosHeaders是 axios 对请求头/响应头的统一抽象所有头字段都存储为实例属性键名不区分大小写但保留首次写入时的原始大小写形式。在请求派发阶段lib/core/dispatchRequest.js#L43 会执行config.headers AxiosHeaders.from(utils.getSafeProp(config, headers))把用户传入的原始头对象统一转换为AxiosHeaders实例响应头同样在 dispatchRequest.js#L68 经AxiosHeaders.from(response.headers)包装。这保证了拦截器、适配器看到的都是同一个类型的方法集。构造函数new AxiosHeaders(headers?)构造函数接受一个可选的头初始化源类型签名为constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);初始化源可以是任意数量的头组成的普通对象键不区分大小写、另一个AxiosHeaders实例或一段以换行分隔的原始 HTTP 头字符串。字符串会被解析后逐条写入实例const headers new AxiosHeaders( Host: www.bing.com User-Agent: curl/7.54.0 Accept: */*); console.log(headers); // Object [AxiosHeaders] { // host: www.bing.com, // user-agent: curl/7.54.0, // accept: */* // }从源码看constructor 的实现只有headers this.set(headers)一行因此构造过程完全复用下面set的解析与写入逻辑三种入参的行为与set完全一致。set写入与覆盖set方法有四种重载支持「单个键值对」「普通对象」「原始头字符串」「可迭代键值对」四种写入方式set(headerName, value: AxiosHeaderValue, rewrite?: boolean | AxiosHeaderMatcher); set(headerName, value, rewrite?: (this: AxiosHeaders, value: string, name: string) boolean); set(headers?: RawAxiosHeaders | AxiosHeaders | string, rewrite?: boolean); set(headers?: Iterable[string, AxiosHeaderValue], rewrite?: boolean);第三个参数rewrite控制覆盖行为这是最容易踩坑的部分false如果该头的值已存在不为undefined则不覆盖undefined默认除非该头的当前值被显式设置为false否则覆盖true无条件强制重写。rewrite也可以传一个用户自定义函数来决定是否覆盖函数接收「当前值、头名称、headers 对象」作为参数。此外有两点值得注意空或纯空白的头名称会被直接忽略Map等可迭代键值对也是合法入参。const headers new AxiosHeaders(); headers.set( new Map([ [X-Trace-Id, abc123], [Accept, application/json], ]) );AxiosHeaders保留它看到的第一个匹配键的大小写形式。如果你需要固定某个头的大小写例如服务端对Authorization的写法敏感可以先用undefined播种一个键之后再写入值——具体做法见 保留特定头大小写 一节。源码视角set 的三个细节覆盖判定set 内部的核心逻辑 是!key || self[key] undefined || _rewrite true || (_rewrite undefined self[key] ! false)时才写入。这解释了为什么「值为false的头」是唯一的防覆盖哨兵也解释了setContentType(application/x-www-form-urlencoded, false)这类「已有值就不改」的常见写法。值清洗所有写入的值都经过 sanitizeHeaderValue——递归处理数组剥离 C0 控制字符与 DEL 字节并修剪首尾空格/水平制表符false和null则原样保留。大小写定位写入前通过 utils.findKey 做小写化线性查找定位已有键命中则复用原键保留原始大小写未命中才以传入形式新建键。get读取与解析get用于获取头的值第二个参数可以是true内置 token 化、AxiosHeaders.parseParameters归一化参数解析、正则或普通函数get(headerName: string, parser: typeof AxiosHeaders.parseParameters): AxiosHeaderParameters; get(headerName: string, parser: RegExp): RegExpExecArray | null; get(headerName: string, matcher?: true | AxiosHeaderParser): AxiosHeaderValue;const headers new AxiosHeaders({ Content-Type: multipart/form-data; boundaryAsrf456BGe4h, }); console.log(headers.get(Content-Type)); // multipart/form-data; boundaryAsrf456BGe4h console.log(headers.get(Content-Type, true)); // parse key-value pairs from a string separated with \s,; delimiters: // [Object: null prototype] { // multipart/form-data: undefined, // boundary: Asrf456BGe4h // } const quotedHeaders new AxiosHeaders({ Content-Type: multipart/form-data; boundarya,b, }); console.log({ ...quotedHeaders.get(Content-Type, AxiosHeaders.parseParameters), }); // { boundary: a,b } console.log( headers.get(Content-Type, (value, name, headers) { return String(value).replace(/a/g, ZZZ); }) ); // multipZZZrt/form-dZZZtZZZ; boundZZZryAsrf456BGe4h console.log(headers.get(Content-Type, /boundary(\w)/)?.[0]); // boundaryAsrf456BGe4h四种解析器语义分别对应 get 源码中的分支无参数返回原始值true走parseTokens正则 token 化遗留行为为向后兼容保留其输出函数以this指向实例被调用正则返回RegExpExecArray | null。传其他类型会抛TypeError(parser must be boolean|regexp|function)。AxiosHeaders.parseParametersRFC 感知的参数解析parseParameters是可选加入opt-in的归一化参数解析器相比get(name, true)的遗留 token 化更严格返回 null-prototype 的参数映射参数名不区分大小写。其规则与 源码实现 一一对应引号字符串quoted-string的分隔引号会被剥离转义的 DQUOTE 与反斜杠对被解码引号内的逗号/分号仍属于值的一部分非引号值仅去除 RFC 规定的可选空白空格与水平制表符OWS参数名必须匹配[!#$%*\-.^_|~0-9A-Za-z]不合法则整段跳过不安全键防护__proto__、constructor、prototype三个键名会被直接丢弃防止原型链污染经由响应头注入。单元测试 tests/unit/axiosHeaders.test.js 覆盖了空引号值、未终止引号、值尾随数据、非 ASCII 空白等边界场景可作为行为验收的参照。has存在性检查has(header: string, matcher?: AxiosHeaderMatcher): boolean;检查某个头是否存在。只有当头的值不为undefined时才返回true可选的matcher会进一步对值做匹配字符串子串、正则或函数均可见 matchHeaderValue 实现。delete删除单个或多个头delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;接受单个头名称或名称数组可选matcher对值做条件匹配。返回true表示至少删除了一个头。源码实现 中数组入参会对每个名称逐一执行带 matcher 的删除并聚合结果。clear按条件批量清空clear(matcher?: AxiosHeaderMatcher): boolean;不传参时删除实例中的全部头传入matcher时只删除匹配的头——注意此时matcher 匹配的是头名称而不是值源码中以isHeaderNameFilter标志切换匹配目标见 clear 实现。返回true表示至少清空了一个头。normalize合并大小写重复键如果头对象被绕过方法直接改过属性headers.Foo 2就可能产生同名但大小写不同的重复键。normalize会把这些重复键合并为一个。Axios 内部会在每次拦截器调用之后使用该方法format传true时把头名称转为小写并大写首字母cOntEnt-type→Content-Type传false则保持原有格式const headers new AxiosHeaders({ foo: 1, }); headers.Foo 2; headers.FOO 3; console.log(headers.toJSON()); // [Object: null prototype] { foo: 1, Foo: 2, FOO: 3 } console.log(headers.normalize().toJSON()); // [Object: null prototype] { foo: 3 } console.log(headers.normalize(true).toJSON()); // [Object: null prototype] { Foo: 3 }normalize返回this支持链式调用。从源码结构看各适配器和数据转换环节都会主动归一化XHR 适配器 与 Node HTTP 适配器 在发送前执行AxiosHeaders.from(config.headers).normalize()fetch 适配器 则执行headers.normalize()后再转为 ByteString 头对象transformData 在请求/响应转换前后也各调用一次——这解释了为什么用户拦截器里随意混写Content-Type/content-type后实际发出的请求仍然只有一个键。concat组合出新实例concat把实例与若干目标合并进一个新的AxiosHeaders实例不修改原实例字符串目标按 RAW HTTP 头解析AxiosHeaders实例与原始对象则按set规则合并concat(...targets: ArrayAxiosHeaders | RawAxiosHeaders | string | undefined | null): AxiosHeaders;这对「预设 覆盖」式组合特别有用const headers AxiosHeaders.concat( { content-type: undefined }, { Content-Type: application/octet-stream } );static concat 的实现 是先以第一个参数构造新实例再按顺序set其余目标——由于set默认覆盖语义后写入的值会覆盖先写入的值undefined播种键的写法由此成立。toJSON 与 toString头的两种输出形态toJSON把内部所有头解析成一个null-prototype的新对象避免原型链属性混入asStrings为true时把数组值拼成逗号分隔的字符串toJSON(asStrings: true): Recordstring, string; toJSON(asStrings?: false): Recordstring, string | string[];实现细节值为null或false的键会被跳过因此「值为false的防覆盖哨兵头」不会出现在最终输出中。toString返回不含 CRLF 的 HTTP 头块每行一个name: value对toString(): string;实现上它基于toJSON()的结果以换行符连接见 源码适合直接打印调试或作为日志输出。from安全构造的统一入口from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;静态方法from从给定的原始头构造新的AxiosHeaders实例若传入的本来就是AxiosHeaders实例则原样返回避免不必要的拷贝。这正是 dispatchRequest 处理请求头、以及适配器处理响应头时所采用的入口。快捷方法ShortcutsAxiosHeaders为常用头生成了 camelCase 命名的set/get/has快捷方法setContentType、getContentType、hasContentTypesetContentLength、getContentLength、hasContentLengthsetAccept、getAccept、hasAcceptsetUserAgent、getUserAgent、hasUserAgentsetContentEncoding、getContentEncoding、hasContentEncoding从源码结构看实际注册的访问器还包括Accept-Encoding与Authorizationindex.d.ts#L83-L96 中有对应类型声明因此快捷方法集合比文档清单更宽。其生成机制是 buildAccessors通过Object.defineProperty把get/set/has 驼峰名定义为代理到通用方法的函数且描述符刻意使用__proto__: null防止被污染的原型把数据描述符劫持成访问器。请求管线中一个真实用例dispatchRequest.js#L49 对post/put/patch请求执行config.headers.setContentType(application/x-www-form-urlencoded, false)——即「只有用户未显式指定 Content-Type 时才用默认值」这正是rewritefalse语义的典型应用。另外类上还有一处「保留名修复」set/get等短名同时也是合法的头名称如headers.SetreduceDescriptors 给这些方法定义了大写名的读写代理使直接给headers.set赋值不会覆盖实例方法本身。方法速查方法签名要点返回值constructor对象 / AxiosHeaders / 换行分隔字符串—set单键值、对象、字符串、Iterablerewrite控制覆盖thisget无参数返回原值true/正则/函数/parseParameters四种解析值 / 解析结果has值非undefined才算存在可加 matcherbooleandelete单名或名称数组可加值 matcher是否删掉至少一个clearmatcher 匹配头名称而非值是否清空至少一个normalizeformattrue转规范大小写合并重复键thisconcat字符串按 RAW 头解析不修改原实例新实例toJSONnull-prototype 对象跳过null/false值对象toString无 CRLF 的name: value多行文本字符串from已是实例则原样返回实例快捷方法setX/getX/hasX含Content-Type等同对应方法所有行为均可在 tests/unit/axiosHeaders.test.js 中找到对应的单元测试验证配合 TypeScript 类型定义 即可在类型安全的前提下完整使用这套 API。【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考