学习如何使用 Node-Fetch NPM 在 Node.js 中发出 HTTP 请求

Sorin-Gabriel Marica,2022 年 12 月 07 日

提出 HTTP 请求是任何现代编程语言最重要的功能之一。Node.js 也不例外,但直到现在,这一功能还掌握在太多的 npm 软件包中。Node-Fetch 通过使用目前大多数浏览器都支持的原始 fetch API,提供了一个替代方案。

Node-Fetch API 简介

在开始介绍 Node-Fetch API 之前,我必须先简单介绍一下什么是 HTTP 请求。HTTP 请求的目的是从互联网上的所有 url 获取信息。HTTP 请求的一个简单例子就是访问网站。

很久以前,HTTP 请求是使用 XMLHttpRequest 或 XHR 对象完成的,而现在所有的现代浏览器都支持 javascript 的 Fetch API。这使得程序员可以使用更简单、更干净的语法来完成请求。然而,Node.JS 服务器端语言长期以来一直缺少获取 API,这就为其他定制软件包提供了实现该功能的空间,例如 Axios、GOT 和许多其他软件包:Axios、GOT 等。

Node-Fetch 等同于 javascript 中的 Fetch API,现在终于可以在 Node.JS 中使用了。

使用 Node-Fetch API 的先决条件

首先,由于这是 Node.JS 教程,您当然需要安装 Node.JS。如果您还没有安装 Node.JS,可以从以下链接下载并安装。

Node.js 仅从 17.5 版本开始发布对 Fetch API 的实验性支持。因此,您至少需要 Node 17.5 版本。此外,您还需要使用 -experimental-fetch标志。

如果您的 Node.JS 版本较低,要跳转到最新版本,可以使用 n 软件包。N 是一个 npmjs 软件包,其唯一目的是允许您在 node 和 npm 版本之间切换。要安装它并切换到最新版本,请按以下步骤操作:

npm install -g n
n latest

最新 n latest命令将安装最新版本的 Node.js。要验证您的 Node.js 版本,只需运行此命令即可:

node -version

如何使用 Node-Fetch

在任何编程语言中进行 HTTP 请求都是异步操作,因为接收请求的响应需要时间。关于如何使用异步操作,有两种方法。一种是等待响应,然后继续编写代码;另一种是并行运行代码。

Node-Fetch 支持同步和异步函数调用。

Node-Fetch 中的 GET 请求

要进行简单的获取请求并从响应中提取正文,可以使用下面的代码:

fetch('https://www.webscrapingapi.com/')

    .then((response) => response.text())

    .then((body) => {

        console.log(body);

    });

要运行这段代码,应将其保存在名为 node-fetch-example.js 的文件中,然后使用此命令在同一文件夹中运行: node --experimental-fetch node-fetch-example.js.请注意,在运行时,您会收到 "Fetch API 是一项实验性功能 "的警告。这很正常,因为在撰写本文时,这只是一项实验性功能。

博客图片

前一段代码在继续执行之前不会等待请求完成。这意味着下面的任何代码都将立即开始执行,而无需等待获取完成。例如,如果您添加了 console.log("Something");的代码,执行脚本时输出将如下所示:

博客图片

为了进一步解释上面的代码,你可能会注意到我们使用了两次 "then "函数。第一个 "then "将在我们收到 HTTP 请求的响应时执行,它的作用是将响应与 response.text()方法的内容进行映射(该方法会返回响应的正文)。但是 text()方法也是异步的,因此我们需要在第二个 "then "中等待它的响应,其中 body 等于 response.text() 承诺的结果。

您也可以像下面的示例一样,使用 await 调用获取 API:

(async () => {

    const response = await fetch('https://webscrapingapi.com');

    const body = await response.text();

    console.log(body);

})();

这就更好地解释了 fetch API 的工作原理,以及需要等待的承诺是什么。在本文中,我们将进一步使用带有 await 的 fetch api,因为这可以让我们的代码语法更简洁。

向请求发送标题

发送请求时需要的另一个功能是设置请求的头信息。为此,您可以在获取 API 的第二个参数中添加头信息,如下所示:

(async () => {

    const response = await fetch('http://httpbin.org/headers', {

        headers: {

            'my-custom-header': 'my-header-value'

        }

    });

    const body = await response.text();

    console.log(body);

})();

除了标头,您还可以在获取 API 的第二个参数中发送更多选项。要查看所有选项,请查阅获取 API(客户端使用的API的文档

Node-Fetch 中的 POST 请求

获取 API 的另一个重要选项是方法选项。它指定了用于 HTTP 请求的方法。你可以使用 5 种方法:GET、POST、PUT、PATCH 和 DELETE,但其中前两种最常用(GET 和 POST)。默认情况下,如果没有指定方法,Node-Fetch 将使用 GET。

要使用 Node-Fetch 发送 POST 请求,可以使用以下代码片段:

(async () => {

    const response = await fetch('http://httpbin.org/post', {

        method: 'POST',

        body: JSON.stringify({

            'key': 'value'

        })

    });

    const body = await response.text();

    console.log(body);

})();
博客图片

您可能会注意到,我们使用 JSON.stringify 发送请求的正文。这是因为 fetch api 会以字符串的形式发送正文,而不是像其他软件包(如 axios)那样以对象的形式发送。

获取 API 还涵盖所有其他请求方法。

节点获取中的错误处理

处理 HTTP 请求时的错误是必须的,因为您永远无法指望第三方服务始终可用。作为最佳实践,您应始终处理错误,以防止您的应用程序或脚本与您所请求的 URL 一起宕机。

node-fetch 中的错误处理可以通过在代码周围使用简单的 try catch 语法来完成。下面是一个示例,说明如何在使用 await 时做到这一点:

(async () => {

    try {

        const response = await fetch('[INVALID_URL]');

        const responseBody = await response.text();

    } catch (error) {

        console.log(error.message);

    }

})();

如果你更喜欢使用 fetch 而不使用 await,那么你可以在代码中添加一个 catch,就像这样:

fetch('[INVALID_URL]')

    .then((response) => response.text())

    .then((body) => {

        console.log(body);

    })

    .catch((error) => {

        console.log(error.message);

    });

节点获取的使用案例

提出 HTTP 请求在很多方面都很有用,因为它可以从不同的服务中获取新信息,并以非常优雅和简单的方式提取数据。在下面的段落中,我们将探讨一些这方面的用例。

使用 Node-Fetch 获取 API 请求

博客图片

编程时,您可能经常需要使用 API。原因是您可能需要从不同的后端来源获取特定数据,然后对其进行处理或更新。一个很好的例子是,有 4 个端点的 API 可以让您从另一个服务器在后端数据库中创建、读取、更新和删除用户(CRUD 操作)。

通常情况下,这样的应用程序接口需要进行身份验证,以防止未经授权的来源使用它,并更改数据使其对自己有利。HTTP 请求有许多认证方法。其中最常见的是使用 API 密钥,API 提供商会给你一个只有你知道的密钥,API 的端点只有在发送正确的密钥时才能工作。

另一种保护应用程序接口的方法是基本认证(Basic Authentication)。这意味着,要访问 API,您需要发送一个包含格式为 "username:password "的 base64 编码字符串的头。下面举例说明如何在 POST 请求中使用基本身份验证:

(async () => {

    const response = await fetch('http://httpbin.org/post', {

        method: 'POST',

        headers: {

            "Authorization": `Basic ${btoa('login:password')}`

        },

        body: JSON.stringify({

            'key': 'value'

        })

    });

    const body = await response.text();

    console.log(body);

})();

使用 Node-Fetch 进行网络抓取

网络抓取(Web Scraping)是一种从网站获取内容并对其进行解析的方法,这样您只需保留所需的数据,并可随意使用。cheerio 是一个很好的 npmjs 库,可以让数据解析变得更容易。通过该库,您可以像使用 javascript 或 jquery 一样,查询从 fetch api 获取的静态 HTML。

下面是一个如何使用获取 API 和 cheerio 获取页面标题的示例:

const cheerio = require("cheerio");

(async () => {

    const response = await fetch('https://www.webscrapingapi.com/');

    const responseBody = await response.text();

    const $ = cheerio.load(responseBody);

    console.log($('title').first().text());

})();

上面的示例应该返回 "WebScrapingAPI | All-In-One Scraping API",因为这是页面的标题(写在浏览器窗口顶部的文字)。细分一下,我们使用 fetch 从https://www.webscrapingapi.com/ 获取 HTML 页面源代码,然后使用 cheerio 解析这些内容。要了解有关 cheerio 的更多信息,请点击此处查看他们的文档 

从其他网站抓取信息在很多方面都很有用。例如,可以利用抓取的信息为机器学习模型创建一个训练数据集,或者创建一个价格比较工具,从多个来源提取数据,然后进行比较。

虽然上面的示例运行良好,但当涉及到刮擦时,fetch api 并不总是最佳选择。这是因为现在的网站都通过 javascript 显示内容,并使用验证码或其他方法来防止数据被搜刮。fetch API 的工作原理是通过简单的 CURL 连接到给定的 url,然后检索页面加载时显示的静态内容,完全不需要任何 javascript 渲染。

要在执行页面上的 javascript 代码的同时刮取数据,您可能需要研究一下 puppeteer 等替代方案,如本文有关高级刮取的描述。不过,如果你不想这么麻烦,可以使用 WebScrapingAPI,它是专门为这项任务设计的 API,可以解决所有这些问题(包括反机器人检测),而且还提供免费试用版,包含所有功能。 

摘要

总而言之,好消息是人们期待已久的获取 api 终于可以在 node.js 中使用了,尽管目前它还只是处于实验功能阶段(撰写本文时)。虽然以前也可以在 node.js 中进行请求,但唯一的方法是通过 XMLHttpRequest/XHR 对象或 Axios 或 GOT 等众多软件包。

这一更改将使客户端 javascript 和服务器端 nodejs 更加相似,因为所有现代浏览器都已在客户端 javascript 中提供并支持这一功能。

进行 HTTP 请求在很多方面都很有用,例如使用 API 或从网站上抓取数据。虽然其他 npm 软件包仍是一种选择,并将继续用于传统项目,但使用 fetch 是未来的最佳解决方案。这将提高 nodejs 代码的可读性,并使从前端到后端的切换变得更加容易。

新闻和更新

订阅我们的时事通讯,了解最新的网络搜索指南和新闻。

We care about the protection of your data. Read our <l>Privacy Policy</l>.Privacy Policy.

相关文章

缩图
指南如何使用 Node Fetch 代理并构建网络抓取器

了解如何将代理与流行的 JavaScript HTTP 客户端 node-fetch 结合使用,以构建网络搜刮程序。了解代理在网络搜刮中的工作原理,将代理与 node-fetch 集成,并构建一个支持代理的网络搜刮程序。

米赫内亚-奥克塔维安-马诺拉什
作者头像
米赫内亚-奥克塔维安-马诺拉什
8 分钟阅读
缩图
指南房地产网络抓取:如何像专业人士一样从 Realtor.com 提取数据

利用专业的网络搜索技术,在房地产行业获得竞争优势。学习如何像专业人士一样从 Realtor.com 中提取有价值的数据,并在游戏中保持领先。

Raluca Penciuc
作者头像
Raluca Penciuc
9 分钟阅读
缩图
指南释放数据的力量:如何从 Booking.com 搜刮有价值的信息

使用 Puppeteer 从 Booking.com 抓取酒店和租房数据。我们的教程教授数据提取和网络抓取,让您深入了解定价、评级等信息。

Raluca Penciuc
作者头像
Raluca Penciuc
8 分钟阅读