Skip to content

Fetch

fetch 是现代浏览器中最常用的网络请求接口。它基于 Promise,和 RequestResponseHeaders 一起构成了较完整的请求模型。

Fetch 的定位

相比 XMLHttpRequestfetch 的特点主要有:

  • API 更简洁
  • 天然使用 Promise
  • 响应体支持流式读取
  • 更适合和 Request / Response / AbortController 组合

它已经是大多数前端项目默认的请求基础能力。

最基础的 GET 请求

js
fetch('/api/items')
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`)
    }

    return response.json()
  })
  .then((data) => {
    console.log(data)
  })
  .catch((error) => {
    console.error(error)
  })

最基础的 POST 请求

js
fetch('/api/items', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    name: 'New Item',
  }),
})
  .then((response) => {
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}`)
    }

    return response.json()
  })
  .then((data) => {
    console.log(data)
  })

常用读取方式

拿到响应对象后,通常还要按内容类型读取响应体。

js
const response = await fetch('/api/items')

常见方法:

  • response.json()
  • response.text()
  • response.blob()
  • response.arrayBuffer()
  • response.formData()

一个重要特点

fetch 不会因为 404500 自动进入 catch。只有真正的网络失败才会 reject。

所以业务里通常要主动判断:

js
if (!response.ok) {
  throw new Error(`HTTP ${response.status}`)
}

发送不同类型的请求体

发送 JSON

js
fetch('/api/items', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ name: 'Tom' }),
})

发送 FormData

js
const formData = new FormData()
formData.append('file', file)

fetch('/upload', {
  method: 'POST',
  body: formData,
})

使用 FormData 时,不要手动设置 Content-Type

和 XHR 的对比

功能点XHRFetch
基本请求能力
Promise 风格
请求取消
流式处理
读取下载进度需结合流处理
传统兼容性更好较新

适合什么场景

  • 常规接口请求
  • async/await 配合
  • 需要 AbortController
  • 需要和 Request / Response / Service Worker 协作

什么时候还会看到 XHR

  • 老项目
  • 上传下载进度依赖 XHR 事件模型
  • 某些兼容性要求较强的场景

基于 MIT 许可发布