十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

axios AxiosHeaders 头方法详解:set、get、normalize、concat 等头部操作 API 的源码级指南

axios AxiosHeaders 头方法详解:set、get、normalize、concat 等头部操作 API 的源码级指南 axios AxiosHeaders 头方法详解set、get、normalize、concat 等头部操作 API 的源码级指南【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axiosaxios 通过AxiosHeaders类提供了一整套结构化的请求/响应头操作 API用于以更规范的方式设置、读取、删除和合并 HTTP 头。本篇技术指南以 axios 官方文档中的 Header methods 章节为主体结合lib/core/AxiosHeaders.js的完整实现与单元测试逐个方法讲解其签名、语义、边界行为如 rewrite 覆盖策略、matcher 匹配规则、大小写保留机制并给出在拦截器、适配器内部实际调用这些方法的位置帮助读者从会用 API进阶到理解其底层机制与坑点。AxiosHeaders 类概览自 axios 引入独立的AxiosHeaders类后头信息不再只是一个普通的键值对象而是一个带方法、支持迭代、大小写不敏感的对象。直接操作头对象如headers[Content-Type] ...会绕过值归一化与大小写管理而通过AxiosHeaders的方法操作可以保证所有键在内部统一做小写比较normalizeHeader实现于 lib/core/AxiosHeaders.js但保留首次写入时的原始大小写通过utils.findKey做 caseless 查找见 lib/utils.js所有值经过normalizeValue清洗false与null表示显式删除该头字符串会被 sanitizeHeaderValue 去除控制字符数组递归处理类方法被utils.freezeMethods冻结lib/core/AxiosHeaders.js防止运行时被覆盖。下文按官方文档脉络依次展开每个方法。构造函数new AxiosHeaders(headers?)AxiosHeaders构造函数接受一个可选的头部源用于初始化实例可以是任意数量的头部对象、AxiosHeaders实例或按换行符分隔的原始头字符串constructor(headers?: RawAxiosHeaders | AxiosHeaders | string);传入原始字符串时axios 会将其解析为逐行的name: value对后加入实例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: */* // }从源码结构看构造函数本体只有一行headers this.set(headers)lib/core/AxiosHeaders.js即构造函数完全复用set的解析逻辑因此set支持的所有输入形态对象、字符串、可迭代键值对在构造时同样可用。其中字符串分支会先经 isValidHeaderName 判断这更像头名还是原始头块若整个字符串不是合法头名则走 parseHeaders 按行解析。测试用例 tests/unit/axiosHeaders.test.js 验证了对象形态构造时数字值会被字符串化headers.get(x) 1。set设置头部与 rewrite 覆盖策略set用于在AxiosHeaders实例上设置头部。它可以接受单个头名 值、包含多个头的对象或换行分隔的原始头字符串并支持可选的rewrite参数控制覆盖行为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参数控制覆盖语义取值含义如下与实现 setHeader 中的判断条件一一对应rewrite 取值行为源码条件false若该头已有值非undefined则不覆盖条件不满足_rewrite true且非 undefined 分支undefined默认覆盖除非该头当前值被显式设为false_rewrite undefined self[key] ! falsetrue无论如何都覆盖_rewrite true自定义函数由函数决定当前值是否应被覆盖函数接收(value, name, headers)经 matchHeaderValue 以filter.call(this, value, header)执行其中值为false表示禁止覆盖的设计与toJSON中跳过false值的行为false等价于该头将被删除/不发送是配套语义。这一点有专门的测试覆盖先set(foo, value1)后set(foo, value2, false)不会改写值而默认set(foo, value2)会改写tests/unit/axiosHeaders.test.js若头被显式设为false默认set也不会覆盖只有rewrite: true才能强行写入tests/unit/axiosHeaders.test.js。其他值得注意的行为空名称被忽略空字符串或仅由空白组成的头名在normalizeHeader后为假值直接返回lib/core/AxiosHeaders.js。可迭代键值对被接受如Map或任何安全的 key/value 迭代器。多个同名键会被合并为数组const headers new AxiosHeaders(); headers.set( new Map([ [X-Trace-Id, abc123], [Accept, application/json], ]) );对应源码中迭代分支会把重复键聚合为[dest, entry[1]]数组lib/core/AxiosHeaders.js。大小写保留AxiosHeaders保留它看到的第一个匹配键的大小写。可以先把键以undefined值占位之后再设置值从而锁定特定大小写详见官方文档 保留特定头的大小写。原型污染防护set的可迭代分支只信任对象自有的Symbol.iterator被污染的Object.prototype[Symbol.iterator]不会被消费该场景有专门的回归测试tests/unit/axiosHeaders.test.js。set方法返回this支持链式调用。get读取头部与三种解析器get用于读取头值第二个参数可以是可选的 matcher 或解析器matcher 默认为true解析器可以是用于从头值中提取信息的正则表达式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)); // 按 \s,; 分隔符解析键值对 // [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 实现 中清晰对应不传解析器原样返回存储值parser true走parseTokenslib/core/AxiosHeaders.js用正则/([^\s,;])\s*(?:\s*([^,;]))?/g把值切分成 null-prototype 键值表函数解析器以this当前AxiosHeaders实例调用参数为(value, key)正则解析器执行parser.exec(value)返回RegExpExecArray | null。传入其他类型会抛出TypeError(parser must be boolean|regexp|function)。AxiosHeaders.parseParameters规范化的参数解析器AxiosHeaders.parseParameters是一个**选择性启用opt-in**的解析器用于解析 HTTP 参数值如Content-Type中的参数部分返回参数名为小写、无原型null-prototype的映射对象。其行为要点剥离引号字符串的分隔符解码被转义的DQUOTE与反斜杠序列实现见 decodeQuotedString引号内部的逗号或分号保留在值中例如boundarya,b解析为boundary: a,b对未加引号的值只去除其两侧符合 RFC 定义的可选空白空格与水平制表符实现见 trimOWS省略危险的对象物化键__proto__、constructor、prototype三个名称会被直接跳过lib/core/AxiosHeaders.js避免原型污染传true则继续使用历史 tokenizerparseTokens保持既有输出以兼容旧行为。has、delete 与 clear存在性检查与删除has检查某头部是否存在于实例中可附带 matcherhas(header: string, matcher?: AxiosHeaderMatcher): boolean;返回true的条件是键存在、值不为undefinedfalse值也算已设置且 matcher 通过若有。源码见 has 实现。delete删除实例上的某个头部接受单个头名或字符串数组与可选 matchermatcher 此时用于匹配头的值delete(header: string | string[], matcher?: AxiosHeaderMatcher): boolean;返回true表示至少删除了一个头。实现见 delete 实现传入数组时会逐个deleteHeader只有 matcher 与值匹配才真正delete对应键。matcher 支持三种形式统一由 matchHeaderValue 处理函数filter.call(this, value, header)、字符串判断值是否包含该子串、正则filter.test(value)。clear不传参数时清空实例中的所有头部传入 matcher 时只删除匹配的头部且此时 matcher 用于匹配头的名称而非值——这是与delete的关键区别源码在 matchHeaderValue 中以isHeaderNameFilter标志将value替换为头名再匹配clear(matcher?: AxiosHeaderMatcher): boolean;返回true表示至少清除了一个头。实现见 clear 实现它通过Object.keys(this)遍历自身自有属性并逐个删除。normalize合并大小写重复键如果头对象被直接修改过绕过set方法可能出现同名但大小写不同的重复键。normalize方法把这些重复键合并为一个axios 在每次拦截器调用后内部都会执行它format设为true时会把名称转为小写并首字母大写cOntEnt-typeContent-Typefalse则保留原格式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 }返回this以支持链式调用。实现见 normalize 实现它遍历所有键用utils.findKey在新表中查找已归一化的键若已存在则把值写入先出现的那个键并删除当前键因此示例中foo: 3保留了首个键foo的名称、取最后处理的值formatHeaderlib/core/AxiosHeaders.js负责小写 按-分段首字母大写的格式化。在 axios 请求链路中normalize的实际调用点可验证这一拦截器之后内部调用的说法数据转换阶段lib/core/transformData.js 在请求/响应转换器前后分别调用headers.normalize()浏览器 XHR 适配器lib/adapters/xhr.js 用AxiosHeaders.from(_config.headers).normalize()取出requestHeadersNode http 适配器lib/adapters/http.js 同样经AxiosHeaders.from(config.headers).normalize()归一化后再写网fetch 适配器lib/adapters/fetch.js 在headers.normalize()后转为ByteString头对象。这意味着在拦截器中直接以任意大小写修改config.headers是安全的——最终发往网络层的头部都会先经过归一化合并。concat合并多个头部源concat将实例与若干目标合并为一个新的AxiosHeaders实例。目标是字符串时按原始 HTTP 头解析是AxiosHeaders实例或普通对象时直接合并。它特别适合组合头部时预置大小写case presetconst headers AxiosHeaders.concat( { content-type: undefined }, { Content-Type: application/octet-stream } );第一个目标以undefined值占位content-type使实例记住了该键的原始小写形式第二个目标写入真实值后由于set的默认语义值为undefined时可以覆盖最终键名保留为content-type而值已是application/octet-stream。concat(...targets: ArrayAxiosHeaders | RawAxiosHeaders | string | undefined | null): AxiosHeaders;返回一个新的AxiosHeaders实例。实现上实例方法concat只是委托给静态方法lib/core/AxiosHeaders.js而 static concat 先用第一个目标构造新实例再对每个后续目标调用computed.set(target)。由于set本身接受字符串/对象/实例静态concat也能作为独立工厂函数使用。toJSON、toString 与可迭代toJSON把内部所有头值解析为一个 null-prototype 对象asStrings设为true时数组值会被解析为逗号分隔的字符串toJSON(asStrings: true): Recordstring, string; toJSON(asStrings?: false): Recordstring, string | string[];实现见 toJSONnull与false值会被跳过——这正是值设为false表示不发送该头的机制落点。toString返回不带 CRLF 的 HTTP 头块每行一对name: valuetoString(): string;实现见 toString本质是对toJSON()的条目做header : value后以换行连接可直接用于调试输出。迭代器AxiosHeaders实现了Symbol.iteratorlib/core/AxiosHeaders.js因此for...of、展开运算符与Object.entries风格的遍历都可以直接使用例如文档示例中的{ ...quotedHeaders.get(Content-Type, AxiosHeaders.parseParameters) }即依赖无原型对象的可展开性。from幂等的实例化from返回基于传入原始头创建的新AxiosHeaders实例若传入的已经是AxiosHeaders实例则原样返回该对象不产生拷贝from(thing?: AxiosHeaders | RawAxiosHeaders | string): AxiosHeaders;实现只有两行static fromthing instanceof this ? thing : new this(thing)。前面提到适配器与transformData都通过AxiosHeaders.from(config.headers).normalize()进入归一化流程from的幂等性保证了配置里放普通对象或AxiosHeaders实例两种方式都能安全处理。Shortcuts访问器快捷方法以下快捷方法开箱即用setContentType、getContentType、hasContentTypesetContentLength、getContentLength、hasContentLengthsetAccept、getAccept、hasAcceptsetUserAgent、getUserAgent、hasUserAgentsetContentEncoding、getContentEncoding、hasContentEncoding源码机制accessor 注册与保留名热修复这些快捷方法并非手写而是由static accessor动态生成。lib/core/AxiosHeaders.js 末尾一次性注册了六个头名Content-Type、Content-Length、Accept、Accept-Encoding、User-Agent、AuthorizationbuildAccessors 对每个头名把名字转为驼峰如content-typeContentType然后在原型上定义getXxx/setXxx/hasXxx三个方法内部分别转发到this.get/set/has.call(this, header, ...)。因此headers.setContentType(application/json)等价于headers.set(Content-Type, application/json)hasContentType()等价于headers.has(Content-Type)。两个值得注意的安全细节null-proto 描述符buildAccessors定义的属性描述符带__proto__: null注释明确说明这是为了防御被污染的Object.prototype.get在途中把数据描述符变成访问器描述符的原型污染手法lib/core/AxiosHeaders.js。保留名热修复utils.reduceDescriptors把原型上每个方法名映射为首字母大写属性setSet、deleteDelete等lib/core/AxiosHeaders.js。这样直接给实例赋headers.delete x这类头名与方法名撞车的操作时实际写入的是this[Delete]数据属性而不会把原型上的delete方法本身覆盖掉。另外源码中还提供了文档未单列的辅助方法getSetCookie()lib/core/AxiosHeaders.js把set-cookie头的值统一规整为数组set-cookie是典型的多值头axios 在响应头解析中会将其存为数组可配合getSetCookie在多值场景下使用。实战建议与验证入口综合文档与源码几条落地建议统一走方法操作始终用set/get/has/delete/clear而非直接键赋值以获得值清洗、false删除语义与大小写管理确需直接赋值后如拦截器里改config.headers依赖 axios 内部的normalize()自动兜底即可见上文各适配器调用点。需要锁定头大小写时先用undefined占位键或AxiosHeaders.concat的 case preset 技巧再写入真实值。解析Content-Type参数如 multipart boundary时优先使用get(name, AxiosHeaders.parseParameters)而非手写正则获得引号、转义与危险键过滤的正确处理。验证行为本文引用的边界行为均可在 tests/unit/axiosHeaders.test.js 中找到对应断言如 rewrite 三态、false值保护、Map迭代与原型污染防护仓库内可用npx vitest run tests/unit/axiosHeaders.test.js运行该测试文件复核仅读取与运行不修改仓库内容。关键文件索引内容路径AxiosHeaders 完整实现lib/core/AxiosHeaders.js原始头字符串解析lib/helpers/parseHeaders.js值清洗lib/helpers/sanitizeHeaderValue.jscaseless 键查找 findKeylib/utils.js数据转换中的 normalize 调用lib/core/transformData.js单元测试tests/unit/axiosHeaders.test.js头部总览与大小写保留文档docs/pages/advanced/headers.md英文原版 header-methods 文档docs/pages/advanced/header-methods.md【免费下载链接】axiosPromise based HTTP client for the browser and node.js项目地址: https://gitcode.com/GitHub_Trending/ax/axios创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表