Api Integration
指导前端与后端API集成的类型、错误、鉴权及实时通信设计规范。
下载 255
基于 undici 的高性能 HTTP 客户端,支持请求、代理、Mock 测试和缓存。
openclaw skills install @openlark/undici命令、参数、文件名以原文为准
Node.js HTTP/1.1 客户端,从零开始编写。作为 Node.js v18+ 内置 fetch() 的底层引擎。当前版本 8.x,支持 ESM/CJS 双模式。
名称含义:意大利语中“十一”的意思 —— 1.1 → 11 → Eleven → Undici(也是《怪奇物语》的彩蛋)
当用户需要执行 HTTP 请求、使用 undici、fetch、代理请求或进行 HTTP 模拟测试时使用。
npm i undiciundici.dispatch() > undici.request() > undici.stream()
> undici.pipeline() > undici.fetch() >> node:http在 50 个 TCP 连接、流水线深度为 10 的情况下,性能约为 axios 的 3-4 倍。
request() — 最高层 API,性能最佳import { request } from 'undici';
const { statusCode, headers, body } = await request('http://localhost:3000/foo');
console.log(statusCode); // 200
console.log(await body.json()); // 解析 JSON
// body 是一个 Web ReadableStream,也可按块读取:
for await (const chunk of body) {
console.log('chunk', chunk);
}
// ⚠️ 必须消费响应体!否则会导致连接泄漏
await body.dump(); // 或 .json() / .text() / for awaitfetch() — 兼容标准 Web APIimport { fetch } from 'undici';
const res = await fetch('https://example.com');
const json = await res.json();
// 使用自定义 Agent
import { Agent } from 'undici';
const res = await fetch('https://example.com', {
dispatcher: new Agent({ keepAliveTimeout: 10000 })
});stream() — 流式处理import { stream } from 'undici';
await stream('http://localhost:3000/foo', { method: 'GET' }, ({ statusCode, headers }) => {
return new Writable({ write(chunk, _, cb) { console.log(chunk.toString()); cb(); } });
});pipeline() — 返回 Duplex 流import { pipeline } from 'undici';
import { Writable, Readable } from 'node:stream';
const duplex = pipeline('http://localhost:3000/foo', { method: 'POST' },
({ statusCode, headers }) => new Writable({ /* ... */ })
);
Readable.from(['data']).pipe(duplex);Agent 负责管理多个目标的连接,并自动复用连接:
import { Agent, setGlobalDispatcher, request } from 'undici';
const agent = new Agent({
connections: 128, // 每个目标的最大连接数
pipelining: 10, // 每个连接的最大流水线深度
keepAliveTimeout: 4000, // keep-alive 超时时间(毫秒)
keepAliveMaxTimeout: 600000,
bodyTimeout: 300000,
headersTimeout: 300000,
});
setGlobalDispatcher(agent); // 设置为全局调度器
const data = await request('http://example.com');| 对比项 | 内置 fetch()(v18+) | undici 模块 |
|---|---|---|
| 依赖 | 无依赖 | 需要安装 |
| 版本 | 随 Node.js 一起发布 | 可获取最新版本 |
| 性能 | 高(存在 Web Streams 开销) | request() 性能最优 |
| API | 仅支持 fetch | 支持 request/stream/pipeline/dispatch |
| 高级功能 | ❌ | ✅ 支持 Agent/ProxyAgent/MockAgent/拦截器 |
| 错误类型 | 包装为 TypeError | 提供更明确的错误信息 |
⚠️ fetch 和 FormData 必须来自同一来源:
// ✅ 正确:完全使用 undici
import { fetch, FormData } from 'undici';
const body = new FormData();
body.set('name', 'value');
await fetch(url, { method: 'POST', body });
// ✅ 或调用 install() 替换全局对象
import { install } from 'undici';
install(); // 之后,全局的 fetch/FormData/WebSocket/EventSource 均来自 undiciimport { ProxyAgent, request, fetch } from 'undici';
const proxyAgent = new ProxyAgent('http://proxy:8080');
// 或带认证:
const proxyAgent = new ProxyAgent({
uri: 'http://proxy:8080',
token: `Basic ${Buffer.from('user:pass').toString('base64')}`
});
// 设置为全局
setGlobalDispatcher(proxyAgent);
// 或局部使用
await fetch('http://example.com', { dispatcher: proxyAgent });import { MockAgent, setGlobalDispatcher, request } from 'undici';
const mockAgent = new MockAgent();
setGlobalDispatcher(mockAgent);
const mockPool = mockAgent.get('http://localhost:3000');
mockPool.intercept({ path: '/foo', method: 'GET' }).reply(200, { ok: true });
const { body } = await request('http://localhost:3000/foo');
console.log(await body.json()); // { ok: true }import { Agent, interceptors, cacheStores, setGlobalDispatcher } from 'undici';
const client = new Agent().compose(interceptors.cache({
store: new cacheStores.MemoryCacheStore({
maxSize: 100 * 1024 * 1024, // 100MB
}),
methods: ['GET', 'HEAD']
}));
setGlobalDispatcher(client);// ✅ 正确做法
const { body } = await request(url);
await body.json(); // 或 .text() / .dump() / for await
// ❌ 错误做法 —— 会导致连接泄漏
const { headers } = await request(url);
// ✅ 如仅需头部信息,建议使用 HEAD 方法
const headers = await fetch(url, { method: 'HEAD' }).then(r => r.headers);undici 不实现浏览器 CORS 机制。在服务器环境中无需预检请求。如需 CORS 保护,需自行实现。
调用 .text() 后再调用 .json() 会抛出 TypeError: unusable。
始终使用 /。不支持 \ 作为路径分隔符。
references/dispatcher.mdreferences/connection.md已收录 23 个 Skill