如何使用HTTP模块在Node.js中创建Web服务器(上)
2020-09-08 11:55:00 Author: www.4hou.com(查看原文) 阅读量:358 收藏

当你在浏览器中查看网页时,其实是在向互联网上的另一台计算机发出请求,然后它会将网页提供给你作为响应。你通过互联网与之交谈的那台计算机就是Web服务器,Web服务器从客户端(例如你的浏览器)接收HTTP请求,并提供HTTP响应(如来自API的HTML页面或JSON)。

服务器返回一个网页需要使用很多软件,该软件通常分为两类:前端和后端。前端代码关心的是内容如何呈现,比如导航栏的颜色和文本样式。后端代码与如何交换、处理和存储数据有关,处理来自浏览器的网络请求或与数据库通信的代码主要由后端代码管理。

Node.js允许开发人员使用JavaScript编写后端代码,尽管传统上它是在浏览器中用于编写前端代码的。这样将前端和后端结合在一起可以减少制作Web服务器的工作量,这是Node.js成为编写后端代码的流行选择的主要原因。

在本文中,你将学习如何使用Node.js中包含的http模块构建web服务器。你将构建可返回JSON数据、CSV文件和HTML网页的Web服务器。

配置

确保在你的开发计算机上安装了Node.js,本教程使用Node.js 10.19.0版本,要将其安装在macOS或Ubuntu 18.04上,请遵循如何在macOS上安装Node.js并创建本地开发环境中的步骤,或如何在Ubuntu 18.04上安装Node.js的使用PPA安装部分中的步骤。

Node.js平台支持开箱即用地创建Web服务器,首先,请确保你熟悉Node.js的基础知识。你可以通过阅读有关如何在Node.js中编写和运行第一个程序的指南来开始使用。

我们还将在其中一节中使用异步编程,如果你不熟悉Node.js中的异步编程或用于与文件交互的fs模块,则可以阅读有关如何在Node.js中编写异步代码的文章来了解更多信息。

步骤1:创建基本的HTTP服务器

首先,创建一个将用户返回纯文本的服务器,这将涵盖设置服务器所需的关键概念,这将为返回更复杂的数据格式(如JSON)提供必要的基础。

首先,我们需要建立一个可访问的编码环境来进行练习,以及本文中的其他内容。在终端中,创建一个名为first-servers的文件夹:

1.png

然后输入该文件夹:

2.png

现在,创建将包含代码的文件:

3.png

在文本编辑器中打开文件,我们将在终端中使用nano:

4.png

首先,加载所有Node.js安装的标准http模块,将以下行添加到hello.js:

5.png

http模块包含创建服务器的函数,稍后我们将看到。如果你想了解有关Node.js中模块的更多信息,请查看我们的如何创建Node.js模块文章。

下一步将定义两个常量,服务器将绑定到的主机和端口:

6.png

如前所述,Web服务器接受来自浏览器和其他客户端的请求。我们可以通过输入域名来与Web服务器进行交互,域名由DNS服务器转换为IP地址。 IP地址是一串唯一的数字序列,用于标识网络(如Internet)上的计算机。有关域名概念的更多信息,请参阅我们的DNS术语、组件和概念介绍文章。

值localhost是一个特殊的私有地址,计算机使用它来引用自己。它通常相当于内部IP地址127.0.0.1,它只对本地计算机可用,对我们已经加入的任何本地网络或互联网都不可用。

端口是服务器用作我们IP地址的终结点。在我们的示例中,我们将为web服务器使用端口8000。端口8080和8000通常用作开发中的默认端口,在大多数情况下,开发人员将使用它们而不是HTTP服务器的其他端口。

当我们将服务器绑定到该主机和端口时,可以通过在本地浏览器中访问http://localhost:8000来访问服务器。

让我们添加一个特殊的函数,在Node.js中,我们将其称为请求监听器。此函数旨在处理传入的HTTP请求并返回HTTP响应。该函数必须有两个参数,一个请求对象和一个响应对象。 request对象捕获传入的HTTP请求的所有数据,response对象用于返回服务器的HTTP响应。

我们希望我们的第一台服务器在有人访问它时返回此消息:"My first server!"。

接下来让我们添加这个函数:

irst-servers/hello.js

7.png

该函数通常根据其函数进行命名,例如,如果我们创建了一个请求监听器函数来返回一个图书列表,则我们可能会将其命名为listBooks()。由于这是一个示例案例,因此我们将使用通用名称requestListener。

Node.js中的所有请求监听器函数都接受两个参数:req和res(如果需要,可以使用不同的名称)。用户发送的HTTP请求被捕获在Request对象中,该对象对应于第一个参数req。我们返回给用户的HTTP响应是通过与第二个参数res中的Response对象进行交互而形成的。

第一行res.writeHead(200);设置响应的HTTP状态代码。 HTTP状态代码指示服务器处理HTTP请求的状态。在本例中,状态代码200对应于“确定”。如果你有兴趣了解Web服务器可以返回的各种HTTP代码以及它们所表示的含义,,那么我们的关于如何排除常见HTTP错误代码的指南是一个很好的起点。

函数的下一行res.end("My first server!");,将HTTP响应写回到请求它的客户端。该函数返回服务器必须返回的所有数据。在本例中,它返回文本数据。

最后,我们现在可以创建服务器并利用我们的请求监听器:

first-servers / hello.js

8.png

通过按CTRL + X保存并退出nano。

在第一行中,我们通过http模块的createServer()函数创建一个新的服务器对象。该服务器接受HTTP请求,并将它们传递给我们的requestListener()函数。

创建服务器后,必须将其绑定到网络地址。我们使用server.listen()方法来实现这一点,它接受三个参数:端口,主机和在服务器开始监听时触发的回调函数。

所有这些参数都是可选的,但是最好明确声明要使用Web服务器的端口和主机。将Web服务器部署到不同的环境时,需要知道正在运行的端口和主机来设置载荷平衡或DNS别名。

回调函数将消息记录到控制台,以便我们可以知道服务器何时开始监听连接。

注意:即使requestListener()不使用req对象,它仍必须是函数的第一个参数。

现在只有不到十五行的代码,我们有了一个Web服务器。让我们看看它的运行情况,并通过运行该程序进行端到端测试:

9.png

在控制台中,我们将看到以下输出:

10.png

注意提示符消失了。这是因为Node.js服务器是一个长时间运行的进程。它只有在遇到导致崩溃和退出的错误时才会退出,或者我们停止运行Node.js进程时才会退出。

在一个单独的终端窗口中,我们将使用cURL(一种用于在网络之间传输数据的CLI工具)与服务器进行通信。输入命令向运行中的服务器发出HTTP GET请求:

11.png

当我们按回车键时,终端会显示如下输出:

12.png

现在,我们已经设置了服务器,并得到了第一个服务器响应。

让我们来分析一下在测试服务器时发生了什么,我们使用cURL向服务器发送了一个GET请求,地址是http://localhost:8000。我们的Node.js服务器侦听来自该地址的连接。服务器将该请求传递给requestListener()函数。函数返回状态码为200的文本数据,然后服务器将响应发送回cURL,后者在终端中显示消息。

在继续之前,让我们按CTRL+C退出正在运行的服务器。这会中断服务器的执行,使我们回到命令行提示符。

在大多数我们访问的网站或使用的API中,服务器响应很少以纯文本形式出现。我们将HTML页面和JSON数据作为常见的响应格式。在下一步中,我们将学习如何以网络上常见的数据格式返回HTTP响应。

步骤2:返回不同类型的内容

我们从Web服务器返回的响应可以采用多种格式。前面提到了JSON和HTML,我们还可以返回其他文本格式,例如XML和CSV。最后,Web服务器可以返回非文本数据,例如PDF,压缩文件、音频和视频。

在本文中,除了我们刚刚返回的纯文本之外,你还将学习如何返回以下类型的数据:

JSON

CSV

HTML

这三种数据类型都是基于文本的,并且是用于在Web上传递内容的流行格式。许多服务器端开发语言和工具都支持返回这些不同的数据类型。在Node.js的上下文中,我们需要做两件事:

· 使用适当的值在我们的HTTP响应中设置Content-Type标头;

· 确保res.end()以正确的格式获取数据。

让我们来看一些示例,在本节中编写的代码,以后的代码与我们之前编写的代码有很多相似之处。 大多数更改存在于requestListener()函数中,让我们使用此“模板代码”创建文件,以便以后的章节更容易理解。

创建一个名为html.js的新文件,稍后将使用此文件在HTTP响应中返回HTML文本。我们将模板代码放在此处,然后将其复制到其他返回各种类型的服务器。

在终端中,输入以下内容:

13.png

现在,在文本编辑器中打开此文件:

14.png

复制“模板代码”,在nano中输入以下内容:

first-servers / html.js

15.png

保存并使用CTRL+X退出html.js,然后返回到终端。

现在,我们将该文件复制到两个新文件中。第一个文件将在HTTP响应中返回CSV数据:

16.png

第二个文件将在服务器中返回一个JSON响应:

17.png

其余文件将用于以后的练习:

18.png

我们现在已经准备好继续练习了,让我们从返回JSON开始。

JSON服务

JavaScript对象表示法通常称为JSON,是一种基于文本的数据交换格式。顾名思义,它是从JavaScript对象派生而来的,但它是独立于语言的,这意味着任何能够解析其语法的编程语言都可以使用它。

API通常使用JSON来接收和返回数据。它之所以受欢迎,是因为其数据传输大小比以前的数据交换标准(例如XML)要小,以及现有的工具可以使程序无需花费过多精力即可解析它们。如果你想了解有关JSON的更多信息,请阅读有关如何在JavaScript中使用JSON的指南

使用nano打开json.js文件:

19.png

我们希望返回一个JSON响应,通过更改突出显示的行来修改requestListener()函数,以返回所有JSON响应都具有的适当标头,如下所示:

20.png

res.setHeader()方法将HTTP标头添加到响应中,HTTP标头是可以附加到请求或响应的其他信息。 res.setHeader()方法采用两个参数:标头的名称和其值。

Content-Type标头用于指示与请求或响应一起发送的数据格式,也称为媒体类型。在这种情况下,我们的Content-Type是application / json。

现在,让我们将JSON内容返回给用户,修改json.js,使它看起来像这样:

first-servers / json.js

21.png

像以前一样,我们通过返回状态码200来告诉用户他们的请求成功。这次在response.end()调用中,我们的字符串参数包含有效的JSON。

通过按CTRL + X保存并退出json.js,现在,让我们使用node命令运行服务器:

22.png

在另一个终端,我们使用cURL到达服务器:

23.png

当我们按回车键时,我们将看到以下结果:

24.png

现在我们已经成功地返回了一个JSON响应,就像我们创建应用程序时使用的许多流行API一样。确保使用CTRL + C退出正在运行的服务器,以便我们可以返回到标准终端提示符。接下来,让我们看一下返回数据的另一种流行格式:CSV。

CSV

逗号分隔值(CSV)文件格式是一种文本标准,通常用于提供表格数据。在大多数情况下,每一行都由换行符分隔,并且该行中的每一项都由逗号分隔。

在我们的工作区中,使用文本编辑器打开csv.js文件:

25.png

让我们在requestListener()函数中添加以下代码:

26.png

这次,我们的Content-Type表示正在返回CSV文件,其值为text / csv。我们添加的第二个标头是Content-Disposition。此标头告诉浏览器如何显示数据,尤其是在浏览器中或作为单独的文件显示。

当我们返回CSV响应时,即使未设置Content-Disposition标头,大多数现代浏览器也会自动下载文件。但是,在返回CSV文件时,我们仍应添加此标头,因为它允许我们设置CSV文件的名称。在这种情况下,我们会向浏览器发出此CSV文件是附件的信号,应下载该文件。然后,我们告诉浏览器文件名称为oceanpals.csv。

让我们在HTTP响应中写入CSV数据:

27.png

就像在我们的响应返回200/OK状态之前一样,这一次,我们对res.end()的调用具有一个有效的CSV字符串。逗号分隔每列中的值,新行字符(\n)分隔行。我们有两行,一行用于表头,另一行用于数据。

我们将在浏览器中测试该服务器。保存csv.js并使用CTRL + X退出编辑器。

使用Node.js命令运行服务器:

28.png

在另一个终端中,使用cURL到达服务器:

29.png

控制台将显示以下内容:

30.png

如果在浏览器中转到http:// localhost:8000,将下载CSV文件。它的文件名将是oceanpals.csv。

使用CTRL+C退出正在运行的服务器,以返回到标准终端提示符。

返回JSON和CSV后,我们介绍了两种API常用的情况,让我们继续介绍如何为人们在浏览器中查看的网站返回数据。

下一篇文章中,我们将继续介绍步骤3和步骤4,创建可以处理各种请求和响应的web服务器。

本文翻译自:https://www.digitalocean.com/community/tutorials/how-to-create-a-web-server-in-node-js-with-the-http-module如若转载,请注明原文地址:


文章来源: https://www.4hou.com/posts/RwBE
如有侵权请联系:admin#unsafe.sh