T
traeai
登录
返回首页
Node.js Blog

Axios 到 WHATWG Fetch 的迁移

8.5Score

TL;DR · AI 摘要

Node.js 推荐从 Axios 迁移到 WHATWG Fetch API,以提升性能和安全性。

核心要点

  • Fetch API 是 Node.js 原生支持的网络请求接口,无需额外依赖。
  • 迁移到 Fetch 可提高代码标准兼容性并减少安全风险。
  • Node.js v18.0.0 或更高版本支持 Fetch API,v21.0.0 后稳定可用。

结构提纲

按章节快速跳转。

  1. 介绍从 Axios 迁移到 WHATWG Fetch API 的原因和优势。

  2. 说明 Node.js 支持 Fetch API 的最低版本要求。

  3. 列出 Axios 方法及其对应的 Fetch 等效方法。

  4. 展示 GET、POST、PUT 和 DELETE 请求的迁移示例。

思维导图

用一张图看清主题之间的关系。

查看大纲文本(无障碍 / 无 JS 友好)
  • Axios to WHATWG Fetch Migration
    • Migration Reasons
      • Native Support
      • Performance Improvement
      • Standards Compliance
      • Security Enhancement
    • Version Requirements
      • Node.js v18.0.0 or later
      • Node.js v21.0.0 or later
    • Supported Methods
      • axios.request
      • axios.get
      • axios.post
      • axios.put
      • axios.delete

金句 / Highlights

值得收藏与分享的关键句。

#Node.js#Fetch API#Axios#迁移
打开原文

AugustinMauroy

[从 Axios 迁移到 WHATWG Fetch](https://nodejs.org/en/blog/migrations/axios-to-fetch#migrate-from-axios-to-whatwg-fetch)

此代码转换工具可将使用 Axios 的代码转换为利用 WHATWG Fetch API 的代码,该 API 现已原生支持 Node.js。

[为何要迁移?](https://nodejs.org/en/blog/migrations/axios-to-fetch#why-doing-this)

  • 原生支持:Fetch 已内置在 Node.js 中,无需外部库及其相关的维护负担。
  • 性能提升:Fetch 针对现代 JavaScript 运行时进行了优化,通常比 Axios 性能更优。
  • 更好的标准兼容性:Fetch 严格遵循 Web 标准,使得编写跨平台代码(同时适用于 Node.js 和浏览器)更加容易。
  • 降低安全风险:移除 Axios 可消除与第三方依赖相关的潜在漏洞,增强应用程序的安全性。

[Node.js 版本要求](https://nodejs.org/en/blog/migrations/axios-to-fetch#nodejs-version-requirements)

  • Node.js v18.0.0 或更高版本(Fetch API 可用,但标记为实验性)
  • Node.js v21.0.0 或更高版本(Fetch API 已稳定)

如果你的包当前支持早于 v18.0.0 的 Node.js 版本,则在不放弃对这些版本支持的情况下无法迁移到 Fetch API。这需要将包的主版本号升级,并更新 package.json 中的 engines 字段,要求 Node.js >= v18.0.0。

[支持的转换](https://nodejs.org/en/blog/migrations/axios-to-fetch#supported-transformations)

代码转换工具支持以下 Axios 方法,并将其转换为对应的 Fetch 等效方法:

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.options(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])
  • axios.postForm(url[, data[, config]])
  • axios.putForm(url[, data[, config]])
  • axios.patchForm(url[, data[, config]])

[示例](https://nodejs.org/en/blog/migrations/axios-to-fetch#examples)

[GET 请求](https://nodejs.org/en/blog/migrations/axios-to-fetch#get-request)

code
const base = 'https://dummyjson.com/todos';

- const all = await axios.get(base);
+ const all = await fetch(base).then(async (res) => Object.assign(res, { data: await res.json() })).catch(() => null);
  console.log('\nGET /todos ->', all.status);
  console.log(`Preview: ${all.data.todos.length} todos`);

[POST 请求](https://nodejs.org/en/blog/migrations/axios-to-fetch#post-request)

code
const base = 'https://dummyjson.com/todos';

- const created = await axios.post(
-     `${base}/add`, {
-         todo: 'Use DummyJSON in the project',
-         completed: false,
-         userId: 5,
-     }, {
-         headers: { 'Content-Type': 'application/json' }
-     }
- );
+ const created = await fetch(`${base}/add`, {
+     method: 'POST',
+     headers: { 'Content-Type': 'application/json' },
+     body: JSON.stringify({
+         todo: 'Use DummyJSON in the project',
+         completed: false,
+         userId: 5,
+     }),
+ }).then(async (res) => Object.assign(res, { data: await res.json() }));
  console.log('\nPOST /todos/add ->', created.status);
  console.log('Preview:', created.data?.id ? `created id ${created.data.id}` : JSON.stringify(created.data).slice(0,200));

[POST 表单请求](https://nodejs.org/en/blog/migrations/axios-to-fetch#post-form-request)

code
const formEndpoint = '/submit';

- const created = await axios.postForm(formEndpoint, {
-     title: 'Form Demo',
-     completed: false,
- });
+ const created = await fetch(formEndpoint, {
+     method: 'POST',
+     body: new URLSearchParams({
+         title: 'Form Demo',
+         completed: false,
+     }),
+ }).then(async (res) => Object.assign(res, { data: await res.json() }));
  console.log('Preview:', created.data);

[PUT 请求](https://nodejs.org/en/blog/migrations/axios-to-fetch#put-request)

code
const base = 'https://dummyjson.com/todos';

- const updatedPut = await axios.put(
-     `${base}/1`,
-     { completed: false },
-     { headers: { 'Content-Type': 'application/json' } }
- );
+ const updatedPut = await fetch(`${base}/1`, {
+     method: 'PUT',
+     headers: { 'Content-Type': 'application/json' },
+     body: JSON.stringify({ completed: false }),
+ }).then(async (res) => Object.assign(res, { data: await res.json() }));
  console.log('\nPUT /todos/1 ->', updatedPut.status);
  console.log('Preview:', updatedPut.data?.completed !== undefined ? `completed=${updatedPut.data.completed}` : JSON.stringify(updatedPut.data).slice(0,200));

[DELETE 请求](https://nodejs.org/en/blog/migrations/axios-to-fetch#delete-request)

code
const base = 'https://dummyjson.com/todos';

- const deleted = await axios.delete(`${base}/1`);
+ const deleted = await fetch(`${base}/1`, { method: 'DELETE' })
+ .then(async (res) => Object.assign(res, { data: await res.json() }));
  console.log('\nDELETE /todos/1 ->', deleted.status);
  console.log('Preview:', deleted.data ? JSON.stringify(deleted.data).slice(0,200) : typeof deleted.data);

[`request` Axios 方法](https://nodejs.org/en/blog/migrations/axios-to-fetch#request-axios-method)

code
const base = 'https://dummyjson.com/todos';
diff
- const customRequest = await axios.request({
-     url: `${base}/1`,
-     method: 'PATCH',
-     headers: { 'Content-Type': 'application/json' },
-     data: { completed: true },
- });
+ const customRequest = await fetch(`${base}/1`, {
+     method: 'PATCH',
+     headers: { 'Content-Type': 'application/json' },
+     body: JSON.stringify({ completed: true }),
+ }).then(async (res) => Object.assign(res, { data: await res.json() }));
console.log('\nPATCH /todos/1 ->', customRequest.status);
console.log('Preview:', customRequest.data?.completed !== undefined ? `completed=${customRequest.data.completed}` : JSON.stringify(customRequest.data).slice(0,200));

[不受支持的 API](https://nodejs.org/en/blog/migrations/axios-to-fetch#unsupported-apis)

该代码转换工具目前尚未覆盖直接请求辅助函数之外的 Axios 功能,例如拦截器、取消令牌或通过 axios.create() 创建的实例配置。

[致谢](https://nodejs.org/en/blog/migrations/axios-to-fetch#recognition)

我们要感谢 Axios 的维护者们长期以来对该软件包的支持以及为生态系统做出的贡献。

AI 可能会生成不准确的信息,请核实重要内容