
H3 Utils 工具集全览可组合 HTTP 框架的轻量功能模块【免费下载链接】h3⚡️ Minimal H(TTP) framework built for high performance and portability项目地址: https://gitcode.com/GitHub_Trending/h31/h3H3 是一个以可组合composable为核心设计理念的极简 HTTP 框架它不提供臃肿的内核而是以一个轻量 H3 实例 为起点围绕请求生命周期提供一系列内置工具函数utilities供开发者按需选取或自由编写自己的工具。本文将系统梳理 H3 Utils 的完整分类体系逐一讲解 Request、Response、Cookie、Security、Proxy、MCP、More 与 Community 八大模块的核心 API、实战用法与源码级实现原理帮助你快速定位并掌握这套即取即用的工具库。从小而精的核心 丰富的工具集理解 H3 的设计哲学H3 的定位是 minimal framework但这并不意味着功能匮乏。恰恰相反它的强大之处在于分层核心只负责事件event、路由与中间件编排而一切业务能力——解析请求体、构造响应、Cookie 操作、安全校验、反向代理、WebSocket、JSON-RPC——都被封装为独立、可组合的工具函数。这种设计带来两个直接收益按需加载用不到的能力不会进入你的代码路径应用保持轻量自由扩展内置工具与自研工具遵循同一套(event) ...的签名约定可以无缝混用。全部内置工具函数统一从 src/index.ts 导出按功能域分组覆盖Request、Query、Response、Middleware、Proxy、Body、Cookie、SSE、Timing、Sanitize、Cache、Path、Static、Base、Session、Cors、Auth、Fingerprint、WebSocket、JSON-RPC 等二十余个类别。文档侧的导航索引 docs/2.utils/0.index.md 将其归纳为八个大类下面逐一展开。Request入站请求的读取与校验对应文档 docs/2.utils/1.request.md该模块负责把原始请求转化为可用的业务数据同时内置了大量安全校验。请求体解析三件套readBody(event, options?)读取请求体并按Content-Type智能解析。默认按 JSON 解析当Content-Type为application/x-www-form-urlencoded时回退为 URL 编码解析其他类型如multipart/form-data必须显式传入options.type: formData才会解析绝不从请求头自动探测。从源码 src/utils/body.ts 可以看到这种严格 opt-in 的设计是为了防止不可信的请求把应用拖入昂贵的 multipart 解析见源码注释中的 #875 问题。readValidatedBody(event, validate, options?)读取请求体后立即用校验器验证。校验器可以是普通函数也可以是 Standard-Schema 兼容的库如 zod、valibot失败时抛出校验错误也可通过options.onError自定义错误响应如返回自定义statusText和汇总的 issues 信息。assertBodySize(event, limit)声明式地限制请求体大小。实现上并非预缓冲而是借助 srvx 的limitRequestBody把请求包装为边读边计数的限流代理一旦累计字节超过limit立即以413中断src/utils/body.ts。它还有两个前置防御诚实的超大Content-Length会在处理前直接413拒绝同时携带Content-Length与Transfer-Encoding的请求会被判定为请求走私RFC 7230并返回400。app.post(/, async (event) { assertBodySize(event, 10 * 1024 * 1024); // 10MB const data await event.req.formData(); });QUERY 方法RFC 10008支持appendAcceptQuery(event, mediaTypes)通过Accept-Query响应头声明资源接受的查询格式如application/sql;charsetUTF-8媒体类型按 Structured FieldsRFC 8941List 序列化。requireContentType(event, acceptedTypes)断言请求Content-Type存在且属于接受列表缺失返回400、格式非法返回422、类型不被接受返回415接受类型支持通配符*、type/*。更常用的请求信息工具getQuery(event)获取解析后的查询字符串对象。getValidatedQuery(event, validate)解析后立即校验查询参数支持函数/zod/valibot可自定义onError。getRequestHost(event, { xForwardedHost? })、getRequestURL(event, opts?)、getRequestProtocol(event, { xForwardedProto? })分别获取主机、完整 URL 与协议。三个函数默认都不信任x-forwarded-*头opt-in因为它是客户端可伪造的输入仅在确认应用运行在会覆写这些头的可信反向代理/CDN 之后才应开启。文档明确警示由Host头推导出的 origin 绝不能用于 CSRF/origin 校验、缓存键或生成发给其他用户的绝对链接除非上游已对 Host 做了白名单固定。getRequestIP(event, { xForwardedFor? })获取客户端 IP。默认来自event.req.ip连接对端或服务器配置信任代理后解析出的客户端地址xForwardedFor: true时改为取x-forwarded-for链中的第一个条目——文档特别提醒该位置正是客户端能自行写入的值启用它等于允许任何调用者自报 IP从而击穿 IP 白名单、限流与审计。更优做法是让服务器如 srvxtrustProxy从右往左解析可信代理链而不要打开此选项。isMethod(event, expected, allowHead?)/assertMethod(event, expected, allowHead?)校验请求方法前者返回布尔值后者不匹配时抛出带Allow响应头的405符合 RFC 9110。allowHead: true时允许对 GET 目标放行 HEAD。getRouterParam(event, name, { decode? })/getRouterParams(event, { decode? })/getValidatedRouterParams(event, validate)读取路由参数。默认返回 URL 中百分号编码的原始形态decode: true时仅解码一层且路径分隔符%2f、%5c及其任意%25嵌套永远不解码——路由按单段匹配的参数绝不能悄悄长出路由与中间件从未见过的/或\。解码一次的结果仍可能包含%XX如%252e%252e→%2e%2e切勿再次 decode否则%2e%2e会还原为../造成路径穿越。app.get(/files/**:rest, (event) { // GET /files/%252e%252e/x getRouterParams(event); // { rest: %252e%252e/x } getRouterParams(event, { decode: true }); // { rest: %2e%2e/x } —— 保持编码勿再解码 });getRequestFingerprint(event, opts)为入站请求生成唯一指纹见 src/utils/fingerprint.ts。requestWithBaseURL(req, base, { url? })/requestWithURL(req, url)/toRequest(input, options?)请求对象的高级操作。toRequest可把输入规范化为 WebRequest若输入是相对 URL则基于host头合成完整路径但协议恒为http忽略x-forwarded-proto且 host 仅作为合成 URL 的 authority无法横向扩展进路径——若需控制 origin请传入绝对 URL。Response响应构造、流式输出与清理对应文档 docs/2.utils/2.response.md该模块覆盖从安全净化到流式传输的完整响应链路。安全净化sanitizeStatusCode(statusCode?, defaultStatusCode)确保状态码为合法 HTTP 状态码。sanitizeStatusMessage(statusMessage)确保状态描述文本安全仅允许水平制表符、空格与可见 ASCII 字符RFC 7230 §3.1.2。流式与动态内容iterable(iterable)按顺序逐块发送内容支持在产出 chunk 的同时穿插异步任务。每个 chunk 必须是字符串或 Buffer生成器yielding函数的返回值与 yield 值同等对待。首个 chunk 会在响应创建前被 await因此第一块之前设置的event.res.status与 headers 仍然生效之后设置的一切都将被忽略头已上线路。源码位于 src/utils/response.ts。return iterable(async function* work() { yield !DOCTYPE html\nhtmlbodyh1Executing.../h1ol\n; for (let i 0; i 1000; i) { await delay(1000); yield liCompleted job #${i}/li\n; } return /ol/body/html; });html(first)/raw(value)安全的 HTML 模板标签。html会自动转义插值raw将一段字符串标记为已信任、已预转义绕过转义直接输出。切勿把用户输入传入raw否则重新引入 XSS 风险。示例html${raw(heading)} ${userName}。noContent(status)返回空负载响应。writeEarlyHints(event, hints)写出HTTP/1.1 103 Early Hints在不原生支持早提示的运行时回退为设置可供 CDN 使用的响应头。重定向redirect(location, status, statusText?)设置location头并默认返回302响应体会附带一个 meta refresh 页面以兜底忽略响应头的老旧客户端。若location来自用户输入必须对照白名单校验否则构成开放重定向漏洞。redirectBack(event, { fallback, allowQuery? })基于referer头返回上一页。默认只取 referer 的pathname剥离查询串与 hashallowQuery: true可保留查询串referer 缺失或跨源时回退到fallback默认/。fallback必须是可信的硬编码路径严禁使用用户输入。生命周期清理onDispose(event, cb)注册一个在事件彻底结束响应体流式传输完成、客户端断开或响应体出错时执行的回调所有运行时均可用回调在全局onResponse钩子之后按注册顺序执行。需注意它表示h3 处理完该事件而非客户端已收到响应若要在仍在产出响应时响应客户端断开如中止上游 fetch应使用event.req.signal。app.get(/sse, (event) { const interval setInterval(() {}, 1000); onDispose(event, () clearInterval(interval)); // ... 返回流式响应 });Cookie读取、写入与块状 Cookie对应文档 docs/2.utils/3.cookie.md实现位于 src/utils/cookie.ts覆盖常规 Cookie 与自动分块的 chunked Cookie 两组 API常规组getCookie(event, name)、parseCookies(event)解析整个Cookie头为键值对象、setCookie(event, name, value, options?)、deleteCookie(event, name, serializeOptions?)、getValidatedCookies(event, validate, { onError? })校验 cookie 值兼容 Standard-Schema。块状组setChunkedCookie(event, name, value, options?)按需自动分块、getChunkedCookie(event, name)读取并按序拼接各块、deleteChunkedCookie(event, name, serializeOptions?)。这一组用于绕过浏览器对单个 Cookie 的大小限制例如存储较大的会话数据。Security认证、会话、CORS 与路径安全对应文档 docs/2.utils/4.security.md这是 H3 工具集中安全密度最高的一类。认证Basic AuthbasicAuth(opts)创建 Basic 认证中间件认证结果写入event.context.basicAuth含username。requireBasicAuth(event, opts)对当前请求就地应用 Basic 认证失败时抛错。import { H3, serve, basicAuth } from h3; const auth basicAuth({ password: test }); app.get(/, (event) Hello ${event.context.basicAuth?.username}!, [auth]);会话useSession(event, config)创建会话管理器getSession/updateSession(event, config, update?)/clearSession分别读取、更新可传差量更新函数与清空会话数据sealSession/unsealSession负责会话数据的加密签名与解密验签。实现位于 src/utils/session.ts基于 src/utils/internal/iron-crypto.ts 的加密原语。指纹getRequestFingerprint(event, opts)为请求生成唯一指纹src/utils/fingerprint.ts可用于限流、防滥用等场景。CORShandleCors(event, options)一站式处理 CORS。若是预检请求自动附加预检头并返回204返回值非false即表示请求已被处理无需后续操作。appendCorsHeaders/appendCorsPreflightHeaders分别向响应追加普通与预检 CORS 头。isCorsOriginAllowed(origin, options)/isPreflightRequest(event)判定 origin 是否放行、判断是否预检请求。app.all(/, async (event) { const corsRes handleCors(event, { origin: *, preflight: { statusCode: 204 }, methods: *, }); if (corsRes ! false) { return corsRes; } // 你的业务代码 });路径安全路径穿越防御的核心resolveDotSegments(path, opts?)解析路径中的./..段且永远不会逃逸到根/之上结果恒为单一前导/的绝对路径杜绝//host协议相对形态。它还会在任意%25嵌套深度解码百分号编码的点段%2e、%252e...并把\规范化为/因此编码或反斜杠式的穿越%2e%2e/、..\..\与字面../一样会被捕获。%2f/%5c编码的路径分隔符默认保持原样尾部./..按目录处理并保留结尾斜杠RFC 3986 §5.2.4内部空段保留/a//b不变仅前导空段钳制为单个/。isCanonicalPath(path, opts?)判断路径是否已处于规范形态即resolveDotSegments会原样返回它。这是解析器自身的快速路径守卫导出它便于在热路径每次请求的 scope 检查或规则匹配上跳过规范化调用——文档强调scope 检查中漏掉一次规范化是绕过漏洞而非性能问题。文档针对路由参数给出了明确警示getRouterParams(event, { decode: true })只解码一层返回值请勿再次解码二次decodeURIComponent会把%2e%2e/x还原为../x、把%00还原为 NUL 字节若参数将用作文件系统或上游路径请用resolveDotSegments解析而非继续解码。Proxy内部子请求与外部代理对应文档 docs/2.utils/5.proxy.md实现位于 src/utils/proxy.ts提供三个层层递进的代理工具fetchWithEvent(event, url, init?)携带事件上下文发起 fetch。内部 URL以/开头通过event.app.fetch()派发为子请求永不出进程继承入站请求的过滤后头经getProxyRequestHeaders与运行时元数据ip、waitUntil等外部 URL则用原生fetch(url, init)原样发送——事件的头与上下文不会被继承向任意主机转发 Cookie/Authorization 是不安全的且流式init.body会自动补上 Node fetch 要求的duplex: half。proxyRequest(event, target, opts)把入站请求代理到目标。请求体流式透传、不缓冲因此此前若读过 bodyreadBody()、readFormData()或读体的中间件会锁死流导致代理失败——需要先检查再代理时请从event.req.clone()读取保持原请求流完好。入站的Cookie与Authorization头会被原样转发对同信任的反向代理是正确行为但对不完全信任的上游请用filterHeaders: [cookie, authorization]剥离。上游 3xx 默认透传而非跟随可设fetchOptions: { redirect: follow }跟随但流式请求体在跟随重定向时可能因 body 无法重放而失败。proxy(event, target, opts)代理请求并把响应回传给客户端。与proxyRequest的关键差异它默认不转发入站头只发送调用方通过opts.headers显式传递的头opts.filterHeaders对它无效仅proxyRequest使用。getProxyRequestHeaders(event)取出已剔除已知会在代理时引发问题的头后的请求头对象。三个函数共同的安全红线永远不要直接把未经净化的用户输入当作url/target调用方必须负责校验与限制目标主机白名单、拦截内部路径、强制协议以/开头的内部 target 会绕过任何外部安全层反向代理认证、IP 白名单、mTLS务必谨慎。MCPJSON-RPC 与 WebSocket 双向通道对应文档 docs/2.utils/6.mcp.md实现位于 src/utils/json-rpc.ts。这一模块让 H3 应用可以直接承担 MCPModel Context Protocol等 JSON-RPC 服务端职责。defineJsonRpcHandler(methods)创建实现 JSON-RPC 2.0 规范的 H3 事件处理器。内置安全默认值要求请求为 JSONContent-Type防 CSRF、拒绝跨源请求防 CSRF 与 DNS rebinding、批处理请求上限 50 条防扇出放大攻击。app.post( /rpc, defineJsonRpcHandler({ methods: { echo: ({ params }, event) Received \${params}\ on path \${event.url.pathname}\, sum: ({ params }, event) params.a params.b, }, }), );defineJsonRpcWebSocketHandler(methods, hooks?)实现 JSON-RPC 2.0 over WebSocket每条入站文本消息作为 JSON-RPC 请求处理并回发响应支持open/close等钩子。安全提示与 HTTP 版本不同它不校验请求Origin——WebSocket 升级不受 CORS 约束任意源页面都能携带访客 Cookie 建立连接跨站 WebSocket 劫持请在upgrade钩子中校验Origin必要时抛出Response中止连接。More基础能力与适配层对应文档 docs/2.utils/9.more.md包含若干高频的基础工具withBase(base, input)返回一个新的事件处理器调用原处理器前先剥离 base 前缀适合把子应用挂载到某一路径下。const api new H3().get(/, () Hello API!); const app new H3().use(/api/**, withBase(/api, api.handler));事件工具isEvent(input)判断是否为 H3Event 对象、isHTTPEvent(input)判断是否为{ req: Request }形态的对象、getEventContext(event)获取/初始化事件上下文存放于req.context、mockEvent(_request, options?)构造模拟事件便于测试。中间件工具bodyLimit(limit)限流中间件基于assertBodySize的随读随限语义超限在读体时以413呈现未被读取的 body 不计数、onError(hook)错误钩子可返回新 Response 优雅兜底、onRequest(hook)/onResponse(hook)请求前/响应后钩子后者可返回新 Response 替换原响应。WebSocket 工具defineWebSocket(hooks)定义 hooksopen/message/close等defineWebSocketHandler(http?)定义 WebSocket 事件处理器——非升级普通 HTTP请求默认返回426 Upgrade Required传入http处理器可让同一路由同时服务 WebSocket 升级与普通 HTTP需要自定义升级握手本身请用 crossws 的upgrade钩子。适配器defineNodeHandler(handler)、defineNodeMiddleware(handler)、fromNodeHandler(handler)、fromWebHandler(handler)用于与 Node.js 生态互操作全部在 src/adapters.ts 中实现并统一从 src/index.ts 导出。Community社区生态工具对应文档 docs/2.utils/99.community.md。H3 的开放性吸引了丰富的社区工具目前收录了多个与 H3 v2 兼容的库Apitally带 H3 插件的 API 监控、分析与请求日志工具H3ravel Framework基于 H3 构建、向 JavaScript 生态移植 Laravel 开发体验的 TypeScript 运行时无关框架Intlify srvmid国际化相关的服务端框架、中间件与工具集Clear Router面向 H3 与 Express.js 的 Laravel 风格路由系统unjwt基于 Web Crypto API、零运行时依赖的底层 JWT 工具JWS/JWE/JWK含 H3 v2 专用的头与 Cookie 会话管理适配器Arkstack以 H3 为一等公民的运行时无关 TypeScript 后端框架。文档同时欢迎社区提交新的兼容库PR 即可收录。如何开始使用 H3 Utils所有工具函数均可直接从包入口导入例如import { readBody, getQuery, setCookie, handleCors, proxyRequest, defineJsonRpcHandler, } from h3;从源码结构看src/index.ts 的 Utils 段是完整的工具清单src/utils/ 目录下每个文件对应一个功能域且每个工具函数都带有完整的 JSDoc 与示例。你可以在 examples 目录找到大量可运行示例如 cookies.mjs、cors.mjs、query-params.mjs、server-sent-events.mjs、websocket.mjs 等在 test 目录找到对应的测试用例如 cookies.test.ts、proxy.test.ts、security.test.ts、json-rpc.test.ts作为行为基准。结语H3 Utils 是小而精核心哲学的完整体现请求解析、响应构造、Cookie、安全、代理、JSON-RPC 等能力都以独立工具函数的形式按需供给且处处内置安全默认值——从 body 的 opt-in 解析、代理的凭据转发策略到路径穿越的编码防御与 Host 头的信任边界每个决策都能在源码与文档中找到明确依据。掌握这套工具集你就能用最少的代码、最强的安全基线构建跨运行时的高性能 HTTP 应用。【免费下载链接】h3⚡️ Minimal H(TTP) framework built for high performance and portability项目地址: https://gitcode.com/GitHub_Trending/h31/h3创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考