fetch

101 阅读4分钟

fetch 是什么

fetch是一个现代的,用于网络请求的 js api

基于 Promise:fetch 的所有操作都返回一个 promise 对象,这使得我们可以用 .then().catch() (注册promise成功失败时要执行的回调函数)以及 async/await 这种更现代、更优雅的方式来处理异步操作,避免了“回调地狱”(Callback Hell)

fetch 操作本身是同步的,但是它会返回一个promise,所以可以使用.then .catch注册成功和失败时的回调函数. .then .catch 都是微任务 触发时会推入微任务队列

第二部分:Fetch 的用法

fetch 的基本语法是 fetch(url, options)。

  • url:你想要请求的地址。(默认是get请求)
  • options (可选):一个配置对象,用于自定义请求,如请求方法请求头请求体等。
1. 基本的 GET 请求

这是最简单的用法,options 参数可以省略,默认就是 GET 请求。

fetch('https://api.github.com/users/github')
  .then(response => {
    // 检查响应状态是否成功 (status code 200-299)
    if (!response.ok) {
      throw new Error('Network response was not ok: ' + response.statusText);
    }
    // 将响应体解析为 JSON
    return response.json(); 
  })
  .then(data => {
    // 在这里处理最终的数据
    console.log(data); 
  })
  .catch(error => {
    // 在这里处理网络错误或上面抛出的错误
    console.error('Fetch error:', error);
  });

关键点解释:

  • 第一次 .then(response => ...) :fetch 返回的 Promise 在收到服务器的响应头后就会立即兑现(resolve),而不是等整个响应体下载完成。这个 response 对象是一个 Response 对象,它包含了响应的状态码、头部信息等,但不直接包含数据
    • response.json() :这是一个方法,用于读取 Response 对象中的响应体(body),并将其解析为 JSON。这个方法本身也返回一个 Promise。其他类似的方法还有 response.text() (解析为文本), response.blob() (解析为二进制对象) 等。
  • 第二次 .then(data => ...) :这个 .then 处理的是 response.json() 返回的 Promise,此时 data 才是我们需要的最终 JSON 数据。
  • .catch(error => ...) :用于捕获**网络层面的错误**(比如DNS解析失败、用户离线)或者我们在代码中手动 throw 的错误。
2. 发起 POST 请求

当需要发送数据给服务器时(如创建新用户、提交表单),你需要使用 POST 请求,并在 options 对象中配置 method, headers, 和 body。

const userData = {
  name: 'John Doe',
  job: 'Developer'
};

fetch('https://reqres.in/api/users', {
  method: 'POST', // 指定请求方法
  headers: {
    'Content-Type': 'application/json' // 告诉服务器我们发送的是 JSON 格式的数据
  },
  body: JSON.stringify(userData) // 将 JavaScript 对象转换为 JSON 字符串
})
.then(response => response.json())
.then(data => {
  console.log('Success:', data);
})
.catch(error => {
  console.error('Error:', error);
});
3. 错误处理(非常重要!) fetch 返回的promise对象只有在 网络失败时 才会成为失败(reject)的状态

fetch 的一个重要特性是:只要服务器有响应,即使响应是 HTTP 错误状态码(如 404 Not Found, 500 Internal Server Error),fetch 返回的 Promise 也不会被拒绝(reject) 。它只会在网络失败(例如,无法连接到服务器)时才会拒绝

因此,你必须手动检查响应状态,如下所示:

codeJavaScript

fetch('https://httpstat.us/404') // 这个地址会返回一个 404 错误
  .then(response => {
    console.log('Response received, status:', response.status); // 会打印 404
    if (!response.ok) { // response.ok 对于 200-299 的状态码为 true
      // 如果状态码不是 2xx,我们手动抛出一个错误
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    return response.json();
  })
  .then(data => {
    console.log(data);
  })
  .catch(error => {
    // .catch() 会捕获到我们上面手动抛出的错误
    console.error('There was a problem with the fetch operation:', error);
  });
4. 使用 async/await 语法

async/await 是处理 Promise 的语法糖,能让异步代码看起来像同步代码,更加清晰。

codeJavaScript

async function postData(url = '', data = {}) {
  try {
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(data)
    });

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

    const result = await response.json(); // 等待 JSON 解析完成
    console.log('Success:', result);
    return result;
  } catch (error) {
    console.error('Error:', error);
  }
}

postData('https://reqres.in/api/users', { name: 'Jane Doe', job: 'Designer' });

fetch 的 response

🧩 一、Response 是什么?

在浏览器中,fetch() resolve一个 Response 对象
它是对 HTTP 响应的封装,属于 Fetch API

它包含:

  • 响应头(headers)
  • 响应体(body)
  • 状态信息(status、ok、type...)
  • 一些工具方法(如 .json().text()

你可以理解为:

Response 就是一个「HTTP 响应报文」在 JS 里的对象化表示。


🧱 二、Response 对象的所有属性总览

属性名类型说明示例值
typestring响应类型(跨域相关)"basic", "cors", "opaque", "error", "default"
urlstring实际响应的 URL(可能重定向后)"https://example.com/data.json"
redirectedboolean是否经过重定向false
statusnumberHTTP 状态码200
statusTextstringHTTP 状态文本"OK"
okboolean状态码是否在 200–299 范围内true
headersHeaders响应头对象Headers { content-type: "application/json" }
bodyReadableStream响应体的流(原始字节数据)ReadableStream { ... }
bodyUsedbooleanbody 是否已被读取false(读取一次后变 true)