JavaScript Fetch API 解释

JavaScript Fetch API 提供了一种直观的方法,用于从在浏览器中运行的应用程序客户端发送网络请求。

它不仅易于上手,还充分利用了现代 JavaScript 的语法特性。本文旨在指导读者如何有效地使用 Fetch API。

什么是 JavaScript Fetch API?

JavaScript Fetch API 是现代浏览器内置的一个接口,允许前端应用发起网络请求。它是对旧式 AJAX XMLHttpRequest 的一种改进替代方案。

它以名为 fetch 的全局函数的形式存在。 当调用此函数并传递参数时,它会返回一个 Promise 对象,该 Promise 对象在请求完成后会解析为响应。 通过使用 fetch 函数,你可以发起各种类型的 HTTP 请求。

Fetch API 相较于其他方法的优势

  • 它拥有更简洁、更直观的接口,上手和使用都更加容易。使用 Fetch API 可以使你的代码更加清晰。 相比之下,XMLHttpRequest 较为复杂,代码不如 Fetch API 简洁。
  • Fetch API 支持 Promise,这使你能够更优雅地编写异步代码。XMLHttpRequest 本身不支持 Promise,而需要通过添加回调函数来处理异步操作。 根据个人偏好,你可能会更倾向于使用 JavaScript Fetch API。
  • 它已成为浏览器内置功能,这意味着你无需引入额外的库即可发起网络请求。 引入额外的库会增大你的 JavaScript 包的体积,并可能降低网站的加载速度。

如何使用 Fetch API

本节将演示如何使用 JavaScript Fetch API 发起不同的网络请求。 你可以使用任何你喜欢的代码编辑器进行编码,只需确保代码在浏览器中运行。 我将直接在 HTML 文件的 script 标签内运行代码。

一个简单的 GET 请求

首先,我们将学习如何发起一个简单的 GET 请求。 实现此目的的代码结构如下:

fetch(url)

因此,如果我们要从 JSONPlaceholder API 获取数据,可以按照以下方式操作:

fetch('https://jsonplaceholder.typicode.com/posts');

此函数调用会返回一个 Promise 对象,该 Promise 对象在 API 响应成功时会被解析,如果发生错误则会返回一个错误。 要访问响应,我们将使用 await 关键字。 但 await 关键字只能在 async 函数中使用。

因此,我们需要使用一个 async 函数包裹 fetch 函数,然后调用它。 如果你对这些概念不熟悉,这里有一篇关于异步 JavaScript 的详细指南。 代码如下所示:

async function getData() {
    const response = await fetch('https://jsonplaceholder.typicode.com/posts');
    console.log(response);
}

getData();

运行以上代码后,你应该在控制台输出中看到类似以下内容:

输出表明 fetch 函数返回了一个 Response 对象。 该对象包含诸如状态码、头部和主体等属性。 响应数据以 JSON 字符串的形式存储在主体中。 因此,我们需要提取这个字符串并解析为 JSON,以便获取 JavaScript 对象形式的数据。

幸运的是,Response 对象提供了一个名为 json() 的便捷方法。 此方法会读取响应主体,并尝试将字符串解析为 JSON 对象。 它会返回一个 Promise 对象,该 Promise 对象会被解析为从 JSON 解析出的对象。

但是,如果主体不是有效的 JSON 字符串,此方法会抛出错误。 因此,我们应该仅在响应状态码为 200 时才尝试解析 JSON。

因此,获取帖子的代码如下所示:

async function getData() {
    const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts"
    );

    if (response.status == 200) {
        const posts = await response.json();
        console.log(posts);
    } else {
        console.log("Something went wrong:", response.status);
    }
}
getData();

运行以上代码将会产生如下结果:

这是一个包含 100 个帖子的数组。

某些 API 端点需要头部信息,例如用于身份验证的头部。 JavaScript Fetch API 提供了简便的方法,可以将头部作为请求的一部分发送。 你需要将一个选项对象传递给 fetch 函数,以指定请求头部。

fetch(url, options);

因此,之前的例子现在看起来像这样:

async function getData() {
    const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts", {
             headers: {
                 'x-auth': '<your auth token>'
             }
         }
    );

    if (response.status == 200) {
        const posts = await response.json();
        console.log(posts);
    } else {
        console.log("Something went wrong:", response.status);
    }
}
getData();

由于 JSONPlaceholder API 不需要身份验证头部,上述代码将和之前一样正常工作。但是,重要的是要了解如何传递头部信息。

传入其他选项

除了传递头部信息外,你还可以将其他许多选项传递给 fetch 函数。 你经常需要用到的两个选项是请求方法和请求主体选项。

我们将通过向 JSONPlaceholder API 发送 POST 请求来演示如何传递这些选项。 这是实现此目的的代码:

async function getData() {
    const response = await fetch(
        "https://jsonplaceholder.typicode.com/posts", {
             method: 'POST',
             body: JSON.stringify({ 
                 title: 'Fetch API',
                 body: 'Lorem Ipsum',
                 userId: 1,
             })
        }
    );

    if (response.status == 200) {
        const posts = await response.json();
        console.log(posts);
    } else {
        console.log("Something went wrong:", response.status);
    }
}
getData();

在我们的选项对象中,我们以属性的形式指定了要使用的请求方法和请求主体。 对于这两个属性,我们都提供了字符串参数。 由于我们想要发起 POST 请求,因此我们将字符串 “POST” 传递给请求方法。 我们还为 body 属性提供了一个 JSON 字符串。 这个 JSON 字符串是通过将具有所需属性的对象字符串化而形成的。

在浏览器中运行此代码将产生以下输出:

输出是一个对象,包含我们刚从服务器接收到的 ID。 这是一个很好的资源,你可以查阅所有可传递的选项。

使用 JavaScript Fetch API 时可能出现的错误

#1. 网络错误

在发送网络请求时,我们经常会遇到错误。当发生网络错误时,fetch 函数会返回一个已解析或拒绝的 Promise 对象。 因此,我们需要将代码包裹在 try/catch 代码块中,以便优雅地处理网络错误。

#2. 其他错误

除了网络错误之外,你还可能遇到其他类型的错误,比如 404、403、500 等。当发生这些类型的错误时,fetch 函数并不会抛出错误。 因此,你需要通过检查响应状态代码来检查这些错误。例如,在前面的例子中,我们仅在状态代码为 200 时才尝试解析响应主体。

#3. CORS 错误

你可能遇到的另一个常见错误是 CORS 错误。 CORS 代表跨域资源共享。源是协议、主机和端口的唯一组合。 例如,我的网站可能在 localhost(主机)的 5500 端口(端口)上运行,并通过 HTTP(协议)提供服务。 因此,该网站的来源将是 http://localhost:5500。

该网站可能会向不同来源的 https://jsonplaceholder.typicode.com API 发出 API 请求。 因此,localhost 和 JSONPlaceholder 这两个来源正在共享资源。 这就是跨域资源共享。但是,API 服务器需要启用 CORS 才能正常工作。 但情况并非总是如此。 处理这类错误的解决方案是通过一个启用 CORS 的代理服务器发送请求。

浏览器支持

Fetch API 是一个相对较新的功能。根据 CanIUse.com的数据,全球大约 95% 的用户拥有支持此功能的浏览器。

总结

JavaScript Fetch API 是一种在语法上更清晰、更优雅的方式,用于在前端编写发送 API 请求的代码。 考虑到浏览器支持的限制,你可能会考虑其他 HTTP 客户端库。