Files
SnowLuma/.pnpm-store/v11/files/14/97d18664e6d3688db9a238960c96220d68b462b76ed8642138627e2fba55f1fea9b36c090ef4febbb6b93a8744f87287c0418fc1fa8f84cf6e4b6c77cc499b
T
TanTan 2a69b23b47
Dev Build / cleanup (push) Waiting to run
Dev Build / typecheck (push) Waiting to run
docs: 仓库链接指向本镜像仓库
2026-11-13 09:27:07 +08:00

282 lines
6.8 KiB
Plaintext

# Getting Started
<!--type=misc-->
## Installation
```bash
npm install undici
```
## Fetch
The quickest way to get started is with `fetch`, which follows the
[Fetch Standard](https://fetch.spec.whatwg.org/) and works the same way as
the browser API:
```mjs
import { fetch } from 'undici'
const res = await fetch('https://example.com')
const data = await res.json()
console.log(data)
```
### Using the Request object
undici also exports a `Request` class that follows the Fetch Standard:
```mjs
import { fetch, Request } from 'undici'
const req = new Request('https://example.com', {
method: 'POST',
headers: { 'content-type': 'application/json' },
body: JSON.stringify({ hello: 'world' })
})
const res = await fetch(req)
console.log(res.status)
```
### Streaming the response
`res.body` is a web `ReadableStream`. Use `pipeline` from
`node:stream/promises` to stream it to a file:
```mjs
import { fetch } from 'undici'
import { pipeline } from 'node:stream/promises'
import { createWriteStream } from 'node:fs'
const res = await fetch('https://example.com/large-file.zip')
await pipeline(res.body, createWriteStream('./file.zip'))
```
> Always consume or cancel the response body. In Node.js, garbage collection
> is not aggressive enough to release connections promptly, so leaving a body
> unread can cause connection leaks and stalled requests. See
> [Specification Compliance - Garbage Collection](/#garbage-collection)
> for details.
For more on `fetch`, see [API Reference: Fetch](api/Fetch.md).
## Dispatchers: Connection reuse and pooling
By default, `fetch`, `request`, `stream`, and `pipeline` create a new connection
for each call. For applications that make many requests to the same origin,
this is wasteful. undici provides **dispatchers** that manage connections
internally.
### `Agent` — for requests to multiple origins
`Agent` is the most general-purpose dispatcher. It pools connections per-origin
and is the recommended default for most applications. Use it with
`setGlobalDispatcher` to affect all undici calls globally:
```js
import { Agent, setGlobalDispatcher, fetch } from 'undici'
const agent = new Agent({
keepAliveTimeout: 30_000,
keepAliveMaxTimeout: 600_000
})
setGlobalDispatcher(agent)
// All subsequent fetch/request/stream/pipeline calls reuse connections
const res = await fetch('https://api.example.com/data')
```
You can also pass a dispatcher per-request:
```js
await fetch('https://api.example.com/data', { dispatcher: agent })
```
### `Pool` — for requests to a single origin
`Pool` manages a fixed set of connections to one origin. It gives you explicit
control over concurrency:
```js
import { Pool, request } from 'undici'
const pool = new Pool('https://api.example.com', { connections: 10 })
const { body } = await request('https://api.example.com/data', {
dispatcher: pool
})
const data = await body.json()
pool.close()
```
### `Client` — for a single connection
`Client` maps to a single TCP connection. It supports pipelining (sending
multiple requests before responses arrive), which should only be enabled for
trusted remote servers:
```js
import { Client } from 'undici'
const client = new Client('https://api.example.com', {
pipelining: 5
})
const { body } = await client.request({ path: '/', method: 'GET' })
await body.dump()
client.close()
```
For more on dispatcher options and lifecycle, see:
- [API Reference: Agent](api/Agent.md)
- [API Reference: Pool](api/Pool.md)
- [API Reference: Client](api/Client.md)
## Timeouts
undici applies timeouts at two levels:
- **`headersTimeout`** — time to wait for response headers (default: 300s).
- **`bodyTimeout`** — time between consecutive body chunks (default: 300s).
Set these on the dispatcher or per-request:
```js
import { Agent, setGlobalDispatcher } from 'undici'
const agent = new Agent({
headersTimeout: 5_000,
bodyTimeout: 30_000
})
setGlobalDispatcher(agent)
```
Timeout errors are thrown as `HeadersTimeoutError` and `BodyTimeoutError`.
See [API Reference: Errors](api/Errors.md) for the full list.
## Error handling
undici exposes structured errors via `error.code`:
```js
import { request, errors } from 'undici'
try {
const { body } = await request('https://example.com')
await body.json()
} catch (err) {
switch (err.code) {
case 'UND_ERR_CONNECT_TIMEOUT':
console.error('Connection timed out')
break
case 'UND_ERR_HEADERS_TIMEOUT':
console.error('Headers timed out')
break
case 'UND_ERR_BODY_TIMEOUT':
console.error('Body timed out')
break
case 'UND_ERR_ABORTED':
console.error('Request was aborted')
break
default:
console.error(err)
}
}
```
### Aborting requests
```js
import { request } from 'undici'
const ac = new AbortController()
setTimeout(() => ac.abort(), 1000)
try {
const { body } = await request('https://example.com', {
signal: ac.signal
})
await body.dump()
} catch (err) {
console.error(err.code) // UND_ERR_ABORTED
}
```
## Common patterns
### Proxies
Use `ProxyAgent` for HTTP(S) proxies, or `EnvHttpProxyAgent` to pick up
proxy settings from environment variables:
```js
import { ProxyAgent, setGlobalDispatcher } from 'undici'
const proxy = new ProxyAgent('http://proxy.internal:8080')
setGlobalDispatcher(proxy)
```
See [Best Practices: Proxy](best-practices/proxy.md) and
[API Reference: ProxyAgent](api/ProxyAgent.md).
### Mocking in tests
```js
import { MockAgent, setGlobalDispatcher, request } from 'undici'
const mockAgent = new MockAgent()
setGlobalDispatcher(mockAgent)
const mockPool = mockAgent.get('https://api.example.com')
mockPool.intercept({ path: '/users' }).reply(200, [{ id: 1 }])
const { body } = await request('https://api.example.com/users')
console.log(await body.json())
```
See [Best Practices: Mocking Request](best-practices/mocking-request.md)
and [API Reference: MockAgent](api/MockAgent.md).
### Testing with undici
For test suites, set short keep-alive timeouts to avoid slow teardowns:
```js
import { Agent, setGlobalDispatcher } from 'undici'
const agent = new Agent({
keepAliveTimeout: 10,
keepAliveMaxTimeout: 10
})
setGlobalDispatcher(agent)
```
See [Best Practices: Writing Tests](best-practices/writing-tests.md).
### Customizing the global fetch
You can override Node.js's built-in globals with `install()`:
```js
import { install } from 'undici'
install()
// Global fetch, Headers, Response, Request, and FormData
// now come from undici, not the Node.js bundle
const res = await fetch('https://example.com')
```
See [API Reference: Global Installation](api/GlobalInstallation.md).
## Further reading
- [Undici vs. Built-in Fetch](best-practices/undici-vs-builtin-fetch.md) —
when to install undici vs using Node.js built-in fetch
- [API Reference](api/Dispatcher.md) — full dispatcher API documentation
- [Examples](/examples/) — runnable code examples