百科.dev
全部条目AI 编程趋势榜开源项目技术资讯提交条目
登录
< 返回工具列表
O

ofetch

> 编程语言
开源

更好的 fetch API。适用于各个地方。

5.3K stars0 点赞0 次浏览
访问官网GitHub

工具介绍

更好的 fetch API。适用于各个地方。

ofetch

A better fetch API. Works on node, browser, and workers.

[!IMPORTANT] You are on v2 (alpha) development branch. See v1 for v1 docs.

Spoiler

Quick Start

Install:

bash
npx nypm i ofetch

Import:

javascript
import { ofetch } from "ofetch";

✔️ Parsing Response

ofetch smartly parse JSON responses.

javascript
const { users } = await ofetch("/api/users");

For binary content types, ofetch will instead return a Blob object.

You can optionally provide a different parser than JSON.parse, or specify blob, arrayBuffer, text or stream to force parsing the body with the respective FetchResponse method.

javascript
// Return text as is
await ofetch("/movie?lang=en", { parseResponse: (txt) => txt });

// Get the blob version of the response
await ofetch("/api/generate-image", { responseType: "blob" });

// Get the stream version of the response
await ofetch("/api/generate-image", { responseType: "stream" });

✔️ JSON Body

If an object or a class with a .toJSON() method is passed to the body option, ofetch automatically stringifies it.

ofetch utilizes JSON.stringify() to convert the passed object. Classes without a .toJSON() method have to be converted into a string value in advance before being passed to the body option.

For PUT, PATCH, and POST request methods, when a string or object body is set, ofetch adds the default "content-type": "application/json" and accept: "application/json" headers (which you can always override).

Additionally, ofetch supports binary responses with Buffer, ReadableStream, Stream, and compatible body types. ofetch will automatically set the duplex: "half" option for streaming support!

Example:

javascript
const { users } = await ofetch("/api/users", {
  method: "POST",
  body: { some: "json" },
});

✔️ Handling Errors

ofetch Automatically throws errors when response.ok is false with a friendly error message and compact stack (hiding internals).

A parsed error body is available with error.data. You may also use FetchError type.

typescript
await ofetch("https://google.com/404");
// FetchError: [GET] "https://google/404": 404 Not Found
//     at async main (/project/playground.ts:4:3)

To catch error response:

typescript
await ofetch("/url").catch((error) => error.data);

To bypass status error catching you can set ignoreResponseError option:

typescript
await ofetch("/url", { ignoreResponseError: true });

✔️ Auto Retry

ofetch Automatically retries the request if an error happens and if the response status code is included in retryStatusCodes list:

Retry status codes:

  • 408 - Request Timeout
  • 409 - Conflict
  • 425 - Too Early (Experimental)
  • 429 - Too Many Requests
  • 500 - Internal Server Error
  • 502 - Bad Gateway
  • 503 - Service Unavailable
  • 504 - Gateway Timeout

You can specify the amount of retry and delay between them using retry and retryDelay options and also pass a custom array of codes using retryStatusCodes option.

The default for retry is 1 retry, except for POST, PUT, PATCH, and DELETE methods where ofetch does not retry by default to avoid introducing side effects. If you set a custom value for retry it will always retry for all requests.

The default for retryDelay is 0 ms.

typescript
await ofetch("http://google.com/404", {
  retry: 3,
  retryDelay: 500, // ms
  retryStatusCodes: [404, 500], // response status codes to retry
});

✔️ Timeout

You can specify timeout in milliseconds to automatically abort a request after a timeout (default is disabled).

typescript
await ofetch("http://google.com/404", {
  timeout: 3000, // Timeout after 3 seconds
});

✔️ Type Friendly

The response can be type assisted:

typescript
const article = await ofetch<Article>(`/api/article/${id}`);
// Auto complete working with article.id

✔️ Adding baseURL

By using baseURL option, ofetch prepends it for trailing/leading slashes and query search params for baseURL using ufo:

javascript
await ofetch("/config", { baseURL });

✔️ Adding Query Search Params

By using query option (or params as alias), ofetch adds query search params to the URL by preserving the query in the request itself using ufo:

javascript
await ofetch("/movie?lang=en", { query: { id: 123 } });

✔️ Interceptors

Providing async interceptors to hook into lifecycle events of ofetch call is possible.

You might want to use ofetch.create to set shared interceptors.

onRequest({ request, options })

onRequest is called as soon as ofetch is called, allowing you to modify options or do simple logging.

javascript
await ofetch("/api", {
  async onRequest({ request, options }) {
    // Log request
    console.log("[fetch request]", request, options);

    // Add `?t=1640125211170` to query search params
    options.query = options.query || {};
    options.query.t = new Date();
  },
});

onRequestError({ request, options, error })

onRequestError will be called when the fetch request fails.

javascript
await ofetch("/api", {
  async onRequestError({ request, options, error }) {
    // Log error
    console.log("[fetch request error]", request, error);
  },
});

onResponse({ request, options, response })

onResponse will be called after fetch call and parsing body.

javascript
await ofetch("/api", {
  async onResponse({ request, response, options }) {
    // Log response
    console.log("[fetch response]", request, response.status, response.body);
  },
});

onResponseError({ request, options, response })

onResponseError is the same as onResponse but will be called when fetch happens but response.ok is not true.

javascript
await ofetch("/api", {
  async onResponseError({ request, response, options }) {
    // Log error
    console.log(
      "[fetch response error]",
      request,
      response.status,
      response.body
    );
  },
});

Passing array of interceptors

If necessary, it's also possible to pass an array of function that will be called sequentially.

javascript
await ofetch("/api", {
  onRequest: [
    () => {
      /* Do something */
    },
    () => {
      /* Do something else */
    },
  ],
});

✔️ Create fetch with default options

This utility is useful if you need to use common options across several fetch calls.

Note: Defaults will be cloned at one level and inherited. Be careful about nested options like headers.

javascript
const apiFetch = ofetch.create({ baseURL: "/api" });

apiFetch("/test"); // Same as ofetch('/test', { baseURL: '/api' })

Adding headers

By using headers option, ofetch adds extra headers in addition to the request default headers:

javascript
await ofetch("/movies", {
  headers: {
    Accept: "application/json",
    "Cache-Control": "no-cache",
  },
});

Access to Raw Response

If you need to access raw response (for headers, etc), you can use ofetch.raw:

javascript
const response = await ofetch.raw("/sushi");

// response._data
// response.headers
// ...

Using Native Fetch

As a shortcut, you can use ofetch.native that provides native fetch API

javascript
const json = await ofetch.native("/sushi").then((r) => r.json());

SSE

Example: Handle SSE response:

javascript
const stream = await ofetch("/sse");
const reader = stream.getReader();
const decoder = new TextDecoder();
while (true) {
  const { done, value } = await reader.read();
  if (done) break;
  // Here is the chunked text of the SSE response.
  const text = decoder.decode(value);
}

️ Proxy Support

[!IMPORTANT] Environment Variables: Bun and Deno respect HTTP_PROXY and HTTPS_PROXY environment variables. Node.js requires setting NODE_USE_ENV_PROXY=1 to enable built-in proxy support.

Node.js

In Node.js (>= 18), you can use the dispatcher option with undici's ProxyAgent.

typescript
import { ProxyAgent } from "undici";

const proxyAgent = new ProxyAgent("http://localhost:3128");

await ofetch("https://icanhazip.com", { dispatcher: proxyAgent });

Example: Set proxy globally for all requests:

typescript
import { ProxyAgent, setGlobalDispatcher } from "undici";

setGlobalDispatcher(new ProxyAgent("http://localhost:3128"));

Example: Allow self-signed certificates (USE AT YOUR OWN RISK!)

typescript
import { Agent } from "undici";

// Note: This makes fetch insecure against MITM attacks. USE AT YOUR OWN RISK!
const unsecureAgent = new Agent({ connect: { rejectUnauthorized: false } });
await ofetch("https://self-signed.example.com/", { dispatcher: unsecureAgent });

Bun and Deno

Bun supports the proxy option:

typescript
await ofetch("https://icanhazip.com", {
  proxy: "http://localhost:3128",
});

Deno can also use undici with npm specifiers for programmatic configuration.

Augment FetchOptions interface

You can augment the FetchOptions interface to add custom properties.

typescript
// Place this in any `.ts` or `.d.ts` file.
// Ensure it's included in the project's tsconfig.json "files".
declare module "ofetch" {
  interface FetchOptions {
    // Custom properties
    requiresAuth?: boolean;
  }
}

export {};

This lets you pass and use those properties with full type safety throughout ofetch calls.

typescript
const myFetch = ofetch.create({
  onRequest(context) {
    //      ^? { ..., options: {..., requiresAuth?: boolean }}
    console.log(context.options.requiresAuth);
  },
});

myFetch("/foo", { requiresAuth: true });

License

Published under the MIT license.

Issues· 0 开放

查看全部 Issues在 GitHub 打开

暂无开放 Issues,或尚未同步最近议题。

> 标签

TypeScript

暂无评论,来聊聊你的看法吧

> 工具信息

发布日期2026年8月1日
最后更新2026年9月17日
分类编程语言
定价开源

> 相关工具

T
TypeScript
JavaScript 的超集,为前端与全栈提供静态类型
P
Python
通用编程语言,广泛用于 Web、数据与 AI
G
Go
Google 推出的简洁高效系统语言