Web-使用 NodeJS 进行服务器端编程

客户端/服务器体系结构

        在研究HTTP之前,我们将简要介绍它们运行环境的属性。这通常称为客户端/服务器环境。

一个简单的客户端/服务器系统具有一个或多个客户端进程和一个服务器进程,如下图所示:

        尽管这看起来很简单,但有几个属性使其比预期的更复杂。客户端是在许多不同的计算机系统上运行的独立实体。这

        意味着我们需要考虑以下方面:

1. 客户端进程必须与客户端操作系统兼容。诸如对语言和数据通信协议的支持之类的内容必须可用且兼容。

2. 安全性是一个问题,因为必须先验证远程客户端,然后才能允许它们访问服务器信息。

3. 许多不同的客户端计算机意味着,最终,一个或多个将在某些客户端/服务器通信过程中中断。这要求设施从这种情况中恢复过来。

4. 如果许多客户端可以访问服务器,则需要支持服务器的可用性和错误恢复,特别是如果客户端/服务器关系是商业客户/供应商关系。

5. 客户端/服务器交互的响应时间必须可接受且可管理。

6. 在网络的互联网规模中,我们还必须考虑客户端如何在数百万台可访问的服务器中找到服务器。

        我们还必须意识到,上图的简单客户端/服务器体系结构并不意味着所有客户端都位于不同的计算机上。在客户端/服务器体系结构中,一个或多个客户端与服务器进程位于同一计算机系统上是完全允许的。

        现代客户端/服务器系统甚至更加复杂。下图说明了我们如何在计算机系统中进行客户端和服务器的任意组合交互。多个客户端与任何一台计算机系统上的多台服务器共存。此外,客户端进程可以访问多个服务器以实现其目标,服务器可以充当客户端来满足自己的客户端需求。

 

        现在您会注意到,在上面的两个图中,箭头下方的术语中间件表示客户端/服务器交互。中间件是客户端/服务器系统实现上述目标所需的软件组件。它是客户端程序和操作系统以及服务器程序和操作系统之间的软件。它通过提供标准化的接口,将与兼容性、安全性、相互定位等相关的复杂因素与客户端和服务器程序员隔离开来。

        我们将在介绍的中间件是超文本传输协议(HTTP)和用于支持它的基础架构。由于该单元(移动系统)的性质,我们将主要对基础设施的客户端感兴趣。但是,了解服务器端发生的情况对于更好地了解该技术的局限性和优势至关重要。

网络服务器

        Web 服务器是基于 HTTP 的客户端/服务器系统的服务器端。它们现在是互联网上的主要服务器技术,主要是因为Web的普及和网络软件设计的发展。虽然HTTP中的“超文本”最初是HTML文档,但现在有更多的数据格式用于HTTP,我们将在本单元中研究其中的一些。在本节中,我们将介绍基本的 Web 服务器操作。在以下各节中,我们将 HTML 修改为文档标记语言,并讨论 HTML 链接如何形成与 Web 服务器的基本交互。然后,我们将查看 <form> 标记,因为它为客户端提供了一种将数据发送到 Web 服务器的方法,允许 Web 服务器构造唯一的页面以发送回客户端。然后,我们将研究允许 Web 服务器执行程序为客户端构建页面的简单 CGI 系统。将研究其他一些取代CGI用于大容量Web服务器,PHP和ASP的现代技术。

        Web 服务器是客户端/服务器与 HTML 页面交互的服务器部分。在最简单的形式中,它只是接受对 HTML 页面的请求,并将存储的页面副本发送到请求客户端。但是,现代Web服务器比这种简单的交互所暗示的要复杂得多。

                典型的 Web 服务器交互中涉及的步骤如下:

1. Web 客户端(通常是 Web 浏览器)通过互联网发送网页请求。

2. 服务器验证请求以确保页面存在,安装任何必需的软件并满足安全约束。

3. 服务器执行客户端请求所需的任何软件。

4. 服务器从服务器文件系统或作为程序的输出收集 HTML 页面。

5. 服务器通过互联网将 HTML 文档发送回客户端。

        步骤 1 和 2 使用 HTTP 协议向服务器发送请求,向客户端发送 HTML 页面。HTTP 是一个非常简单的协议,它使用 REQUEST 和 RESPONSE 消息在客户端和服务器之间进行交互。虽然我们不需要知道HTTP的细节,但查看这些消息的一般格式很有用。下表显示了 HTTP 请求消息和示例消息的一般形式。        

HTTP 请求的一般形式 示例请求
method resource_id HTTP_version
header:value
header:value
blank_line
message_body

GET /jdk1.3/docs/index.html HTTP/1.0

Accept: text/html

User-Agent: MacWeb

        在此示例中,方法“GET”是可能的 HTTP 方法之一。HTTP 版本为 1.0,在本例中,没有消息正文。请注意,资源标识符只是服务器上资源的文件名。服务器的计算机名称不是必需的,因为要发送消息,客户端必须已经找到服务器名称才能知道将消息发送到何处。

        下表显示了 HTTP 响应的一般形式和包含 HTML 页面的实际示例响应。

HTTP 响应的一般形式 示例响应

HTTP_version result_code result_comment

header:value

header:value

blank_line

message_body

HTTP/1.0 200 OK

Server: Apache/1.3

Mime_version: 1.0

Content_type: text/html

<html> … </html>

        此 HTTP 响应使用协议版本 1.0,并返回结果代码 200。它的标头/值对指示服务器是 Apache 版本 1.3 服务器,并在消息正文中发回 HTML 页面。

        您现在已经遇到了通用资源定位符 (URL)。例如,以下 URL 标识位于 Web 服务器上名为 spike.scu.edu.au 的 /jdk1.3/docs/index.html 的网页,该网页可通过 HTTP 协议访问。

http://spike.scu.edu.au/jdk1.3/docs/index.html

        HTTP 请求消息只需要 Web 服务器上的文件位置,因为协议 (HTTP) 是由 URL 的第一部分选择的,并且服务器已经使用 URL 中的计算机名称找到,在这种情况下 spike.scu.edu.au。您可能已经看到其他协议,例如URL中使用的HTTPS和FTP(https:和ftp:)。

服务器端编程

        服务器端编程是指直接在服务器内开发或编程的过程。

        使用服务器端编程的好处是基础数据可以在本地访问;无需网络连接或外部资源即可访问数据。此外,在服务器上运行的嵌入式代码通常比客户端代码快,客户端代码要求用户访问数据库才能访问数据。我们将在第 4 周模块中使用 NodeJS 研究数据库访问。

        此外,服务器端编程允许将代码直接合并到数据库中。可以使用标准数据库备份工具管理和还原代码,就像任何其他数据库对象一样。

        在本节中,我们将在服务器端编程语言的上下文中讨论 NodeJS,并探索使用 NodeJS 构建我们的第一个服务器应用程序所需的概念。但在此之前,我们将重新审视一些重要主题,例如HTTP,构建我们的第一个服务器应用程序所需的API。

超文本传输协议 (HTTP)

        作为本模块的一部分,需要了解超文本传输协议(HTTP),这是计算机网络使用的协议。还有其他协议,如SMTP(简单邮件传输协议),FTP(文件传输协议),POP3(邮局协议3)等。

        协议提供明确定义的消息格式、规则、语法、语义等,允许具有不同硬件和软件的设备相互交互。与特定协议兼容的任何设备都可以与网络上的任何其他设备进行通信。

        超文本传输协议(HTTP)可以说是有史以来采用最广泛的互联网应用协议之一。它是客户端和服务器通过互联网进行通信的方法。除了浏览器之外,HTTP是几乎所有连接到互联网的应用程序的首选协议。

        大多数操作系统默认包含网络协议(例如HTTP)的事实意味着我们不必安装任何其他软件即可访问Internet。

        驱动 Web 的 HTTP 协议称为无连接协议。它是 Web 浏览器用来与 Web 服务器通信的协议。每次单击链接、提交表单或执行搜索时,都会从浏览器向目标服务器发送请求。从服务器请求图像、视频和文本后,浏览器和服务器将不再连接。这是因为它基于请求/响应模型运行。

        提交请求时,必须包含标识资源的 URL 以及将应用的方法(例如检索、删除或发布)。可以以 URL 参数(字段值对)、POST 数据或 Cookie 的形式包含其他信息。

        HTTP 协议为客户端和服务器之间的通信制定了明确的准则。

  • 通常,HTTP 请求仅由客户端发送到服务器。服务器响应来自客户端的 HTTP 请求。通过使用称为服务器推送的技术,服务器还可以在请求信息之前将信息填充到客户端的缓存中。
  • 通过 HTTP 请求文件时,客户端必须提供文件的 URL。
  • Web 服务器必须响应每个 HTTP 请求,至少要响应错误消息。

HTML 和表单<form>标记

        您已经在前面的单元中看到了 HTML <form> 标记。到目前为止,我们还没有讨论的是我们应该如何将数据发送到远程服务器并管理数据传输中发生的延迟和错误。因此,作为修订,我们将在此处重新访问正常的 HTML <form> 标记。

        从 Java 网站 (java.sun.com) 获取的 HTML <form> 标记的示例如下:

  <form action="/cgi-bin/coffee" method="post">
    Would you care for a cup of coffee?<BR>
    <INPUT type="radio" name="coffee" value="Y" CHECKED="checked"/>Yes
    <INPUT type="radio" name="coffee" value="N"/>No<P>
    If yes:<BR/>
    What flavor?
    <SELECT name="flavor" size="1">
      <OPTION value="French Roast"/>French Roast
      <OPTION value="Vienna Roast"/>Vienna Roast
      <OPTION value="Almond Mocha"/>Almond Mocha
    </SELECT><BR/>
    <INPUT type="checkbox" name="cream" value="Y"/>Include Cream
    <INPUT type="checkbox" name="sugar" value="Y"/>Include Sugar<br/>
    <INPUT type="submit" value="Brew It"/>
  </form>

        此 <form> 标记的 action 属性指定一个程序来处理要发送到服务器的数据(在本例中为 /cgi-bin/coffee)。Web 服务器使用此信息来启动程序来处理数据。方法属性使用其 post 值指定应在将数据发送到服务器的 HTTP 请求中使用 HTTP POST 方法。

        此标记还构造一组可视控件,这些控件允许客户端用户通过解释由 <form> 和 </form> 分隔的标记来选择要发送到 Web 服务器的值。浏览器将显示类似于下图的内容。

        在此示例中,<input> 标记用于构造单选按钮、复选框和表单底部的“Brew It”按钮。<select>标签用于构建一个下拉菜单,允许用户选择咖啡的类型。

通用网关接口 (CGI)

        在上一节中,我们研究了如何使用 <form> 标记从用户那里收集数据以发送到服务器进行处理。第一个使用此数据的服务器端系统是通用网关接口,它始终简称为 CGI。

        CGI是一个简单的系统,其中Web服务器启动一个称为CGI程序的程序来处理表单数据。然后,CGI程序生成一个HTML网页,服务器将其发送回客户端。下图显示了客户端和服务器之间的完整交互。

        此图显示了表单如何首先从 Web 服务器加载,可能是通过先前的 CGI 请求加载的。然后,客户端用户操作表单并将表单数据发送到服务器进行处理。然后,服务器启动处理 CGI 程序,该程序由 <form> 标记中的操作属性指定,该程序从客户端读取数据并生成一个 HTML 页面供服务器发送回客户端。最后,客户端显示生成的网页。

        当用户单击提交按钮或替代提交交互时,例如执行适当的JavaScript函数,数据由Web浏览器组装。在传输到服务器之前,数据被组装成标签/值对。这些对以标签=值的格式排列,单独的对用“&”字符分隔。浏览器还会将特殊字符替换为可能通过 HTTP 传输的字符,例如,空格替换为“+”。

        CGI 程序从 Web 服务器获取相同标签/值对中的客户端数据。例如,假设我们从上一节中选择了咖啡示例的控件,如下图所示。

        浏览器将构造以下字符串以发送回CGI程序,并使用HTTP POST方法将数据发送回CGI程序:

  flavor=Vienna+Roast&cream=Y&coffee=Y

        现在,您应该仔细将其与上面给出的HTML代码进行比较。请注意,标签的顺序与在 HTML <form> 标记中声明的顺序不同。一般来说,情况就是这样,CGI程序不能依赖于标签的任何顺序。另外,请注意标有糖的复选框如何在此字符串中未表示。通常,未选中复选框时也是如此,即仅选中复选框返回标签/值对。

        客户端/服务器交互的下一步是 Web 服务器接收 HTTP POST 请求,并使用环境变量将 HTTP 消息详细信息传递给指定的 CGI 程序。然后,CGI 程序检索环境变量以确定 HTTP 请求的模式。请注意,您之前可能已经看到过环境变量,例如 PATH 或 CLASSPATH。CGI系统使用不同的变量,这些变量可以被CGI程序检索。

        在此示例中,CGI 程序将发现 CGI 请求正在使用 POST 模式,以便它能够从程序标准输入中读取标签/值对。程序必须解释传递的字符串以删除各种插入的字符(“=”、“?”、“+”等)。该程序将构建一个内部数据结构以包含标签及其关联值。

        然后,CGI程序可能通过访问数据库,文件和其他程序来处理数据。最后,CGI程序将HTML页面直接写入程序的标准输出流。这可以在Java CGI程序中完成,例如,通过使用System.out.println()函数。

        当 CGI 程序关闭其标准输出或退出时,Web 服务器会将 HTML 页面发送回客户端。如果客户端是 Web 浏览器,则它会显示网页。

        CGI有几个问题,使其不适合大容量Web服务器:

        1.CGI系统速度慢。这是因为 Web 服务器必须为每个 CGI 请求启动一个新程序。启动CGI程序需要将许多系统资源放在一起,并从文件系统加载程序。更好的系统使用在计算机内存中保持运行的程序来避免这些问题。

        2.CGI是无国籍的。无状态意味着 CGI 程序不记得哪个客户端发送了上一个 CGI 请求,因此它不记得客户端在最后一个请求上做了什么。这意味着CGI交互通常是一屏一响应的应用程序,已经引入了cookie和其他状态保存设备来解决这个问题。

        3.CGI编程困难。问题2的解决方案使CGI编程变得相当复杂。更好的系统已经发展到使编程更容易。

具象状态转移 (REST)

        具象状态传输 (REST) 已成为基于 HTTP 协议组织应用程序的常用方法。它以自然且高度关联的方式使用 HHTP 消息标头和协议属性。在本节中,我们将概述 RESTful(众所周知)Web 服务实现的主要功能。

        REST Web 服务有四个主要方面:

        1. 使用HTTP,消息类型(GET,POST,PUT等)具有明确的含义;

        2. 通信是无状态的;

        3、数据的目录结构暴露给客户端和服务器;和

        4. 数据以 XML 或 HTTP 标头中指定的其他 MIME 类型传输。

使用 NodeJS 创建 Web 服务器并加载 HTML 文件

        先决条件:
  • 确保 Node.js 已安装在您的计算机上
  • 已学习创建 Web 服务器所需的基础知识。
        创建网络服务器:
  1. 创建一个名为“我的服务器”的新文件夹
  2. 在新创建的文件夹 my-server 中创建一个名为“web-server.js”的新文件
  3. 将以下代码添加到文件“web-server.js”。
        首先要做的是加载任何 Node.js 安装中标准的 http 模块。http 模块包含创建服务器的函数。
const http = require("http");

        下一步,我们将定义两个常量,即将分配给服务器的主机和端口:

const host = 'localhost';
const port = 8080

        Web 服务器处理来自浏览器和其他客户端的请求,正如我们在前面的部分中讨论的那样。通过使用域名,可以与 Web 服务器进行交互,Web 服务器由 DNS 服务器转换为 IP 地址。localhost是计算机连接到网络时给定的地址的名称,也称为环回地址。也称为“内部IP地址127.0.0.1”,它仅在本地计算机上可用,而不适用于我们所属的任何网络或Internet。

        所有网络连接设备都有标准化端口,每个端口都有一个唯一的编号。有许多端口是为特定协议保留的。例如,端口 80 是为超文本传输协议 (HTTP) 消息分配的默认端口。

        IP 地址允许与特定设备之间传输消息。另一方面,端口号使特定服务或应用程序能够针对特定设备并充当网关。这里我们使用 8080 作为我们的端口号。如果服务器已成功设置,我们应该能够通过 http at http://localhost:8080 访问它。

        访问服务器后,下一步将是显示消息。为此,我们需要创建一个函数。

const requestLis = function (req, res) {
    res.end("Hello world, this is my first web server using NodeJS");
};

        在 Node.js 中,所有请求侦听器函数都接受两个参数,req 和 res。用户的 HTTP 请求在请求对象中捕获,该对象对应于第一个参数 req。第二个参数 res(res)中的响应对象用于生成返回给用户的 HTTP 响应。res.end() 函数将 HTTP 响应返回给客户端。

        最后一步涉及创建我们的服务器并将其配置为使用请求侦听器与客户端通信。
const server = http.createServer(requestLis);
server.listen(port, host, () => {
    console.log(`Server is up and running on http://${host}:${port}`);
});

        现在,保存文件并转到Powershell或终端并执行以下命令

node web-server.js

        您现在应该能够在PowerShell/终端上查看以下信息。

Server is up and running on http://localhost:8080

使用 NodeJS 加载 HTML 文件:

        使用我们在前面部分中讨论的 fs 模块,我们可以加载 HTML 文件并在编写 HTTP 响应时使用它们的数据。

        创建将由 Web 服务器返回的 HTML 文档。

index.html

        向 html 文件添加一些代码以使网页具有吸引力。

        通过将以下代码写入 Web 服务器来导入 fs 模块.js以使用加载 HTML 文件所需的 readFile() 函数.

const fs = require('fs').promises;

        为了符合现代Javascript的最佳实践,我们使用了一个promise变体,因此.promises。

        最后将以下代码添加到 Web 服务器.js.

使用 Express 创建 HTTP 服务器(Node.js 框架)

        各种框架,如 Express.js 和 Koa.js可用于 Node.js。这些框架提供了各种有用的中间件功能,以及开发人员可以利用而不是开发自己的许多其他有用功能。在本课程中,我们将探索 Express.js 框架并创建一个 HTTP 服务器。

        为了使用Express框架,首先,你需要安装express。为此,您必须转到Powershell /终端并输入以下命令.

npm install express

        然后使用 require() 函数导入名为 express 的模式。为了使用 Express 框架,您必须首先使用 require() 函数导入名为 express 的模式 下面是如何使用 Express 框架导入模块的示例。

const express = require('express');
const app = express();

        调用require()函数最初将模块的名称指定为字符串('express'),然后调用返回的对象以创建Express应用程序。然后,可以访问应用程序对象的属性和函数。

        创建一个名为 app.js 的新文件,并使用以下代码.

const express = require('express');
const app = express();
const port = 8000;

app.get('/', function(req, res) {
  res.send('Hello World!')
});

app.listen(port, function() {
  console.log(`Example app listening on port ${port}!`)
});

        转到Powershell或终端并运行代码

node ./app.js

猜你喜欢

转载自blog.csdn.net/qq_54813250/article/details/133431438