Skip to content

Node.js Web 模块 (Web Module)

Web 服务器是监听传入网络请求的软件(有时也包括硬件),这些请求通常通过 HTTP 或 HTTPS 协议发送,由 Web 浏览器等客户端发起。它处理这些请求并返回响应,通常是以 HTML 文档、JSON 数据、图像、样式表或其他资源的形式。

现代 Web 服务器通常处理动态内容生成。它们可能会执行服务器端代码(如 Node.js 脚本),与数据库交互,或与后端服务通信,以生成针对客户端的定制响应。

虽然存在像 Nginx 或 Apache 这样的流行专用 Web 服务器,但 Node.js 允许你使用其内置的 http 模块直接在应用代码中构建自己的 Web 服务器。

Web 应用通常遵循分层架构:

  • 客户端(Client): 用户界面,通常运行在 Web 浏览器或原生移动应用中。它向服务器发送请求。
  • 服务器(Web 层)(Server (Web Layer)): 这一层通常使用 Node.js 和像 Express 这样的框架构建,接收客户端请求,处理路由(routing),执行初始验证(validation),并与业务逻辑层(Business Logic)协调。
  • 业务逻辑(Business Logic): 包含核心应用逻辑、规则和处理过程。它与数据层(Data Layer)交互以完成请求。
  • 数据层(Data Layer): 管理数据持久化(data persistence),通常涉及数据库(SQL 或 NoSQL)或其他数据存储。

Node.js 通常在服务器(Web 层)运行,并且也可以实现业务逻辑,特别是在小型应用或微服务中。

使用 Node.js 创建一个基础 Web 服务器

Section titled “使用 Node.js 创建一个基础 Web 服务器”

Node.js 提供了内置的 http 模块来创建 HTTP 服务器和客户端。这是一个 HTTP 服务器的最小示例,它监听端口 3000 并响应 ‘Hello World!’。

创建一个名为 server.js 的文件:

文件: server.js

// 导入内置的 http 模块
const http = require('http');
const hostname = '127.0.0.1'; // 标准回环接口地址 (localhost)
const port = 3000;
// 创建服务器
// createServer 方法接受一个回调函数,该函数会在每个传入请求时执行。
// 此函数接收两个参数:
// req: 请求对象 (incoming message)
// res: 响应对象 (server response)
const server = http.createServer((req, res) => {
console.log(`收到来自 URL: ${req.url} 的请求,方法为: ${req.method}`);
// 设置状态码为 200 (OK)
res.statusCode = 200;
// 设置 Content-Type 头部为纯文本
res.setHeader('Content-Type', 'text/plain');
// 写入响应体
res.end('Hello World!\n');
});
// 开始监听传入连接
server.listen(port, hostname, () => {
console.log(`服务器运行在 http://${hostname}:${port}/`);
});
  • require('http'): 加载 Node.js 的 HTTP 模块。
  • http.createServer((req, res) => { ... }): 创建一个 HTTP 服务器实例。提供的回调函数是请求监听器(request listener),在每次请求到达服务器时执行。
  • req (请求对象): 一个包含传入请求信息的对象,如头部(req.headers)、URL(req.url)和 HTTP 方法(req.method)。
  • res (响应对象): 用于向客户端发送所需响应的对象。你可以设置头部(res.setHeader)、状态码(res.statusCode)和响应体(res.end)。
  • res.end('Hello World!\n'): 发送响应体(‘Hello World!’)并标志响应已完成。
  • server.listen(port, hostname, () => { ... }): 告诉服务器开始监听指定端口和主机名上的连接。回调函数在服务器成功启动后执行。

现在,从你的终端运行服务器:

$ node server.js

验证终端中的输出:

Server running at http://127.0.0.1:3000/

向 Node.js 服务器发起请求:

打开你的 Web 浏览器并访问 http://127.0.0.1:3000/。你应该会看到显示“Hello World!”的文本。

再次检查服务器终端。你应该会看到一条日志消息,表明接收到了请求:

收到来自 URL: / 的请求,方法为: GET

http 模块也可以用来向其他服务器发起 HTTP 请求。尽管通常使用像 axios 或内置的 fetch API(在最近的 Node.js 版本中全局可用)等更高级的库来完成,这里演示如何直接使用 http 模块。

创建一个名为 client.js 的文件(确保 server.js 仍在运行):

文件: client.js

const http = require('http');
const options = {
hostname: '127.0.0.1',
port: 3000,
path: '/',
method: 'GET'
};
// 发起请求
const req = http.request(options, (res) => {
console.log(`状态码 STATUS: ${res.statusCode}`);
console.log(`头部 HEADERS: ${JSON.stringify(res.headers)}`);
// 为响应数据设置编码
res.setEncoding('utf8');
let responseBody = '';
// 数据以块(chunk)的形式接收
res.on('data', (chunk) => {
responseBody += chunk;
console.log(`响应体块 BODY CHUNK: ${chunk}`);
});
// 'end' 事件表示整个响应已接收完毕
res.on('end', () => {
console.log('\n--- 响应完成 Response Complete ---');
console.log(responseBody);
console.log('响应中没有更多数据 No more data in response.');
});
});
// 处理请求期间可能发生的错误
req.on('error', (e) => {
console.error(`请求出现问题 Problem with request: ${e.message}`);
});
// 结束请求(重要!)- 这会发送请求
req.end();

在另一个终端窗口中运行 client.js:

$ node client.js

验证客户端输出。你应该会看到从服务器接收到的状态码、头部信息和 ‘Hello World!’ 响应体:

状态码 STATUS: 200
头部 HEADERS: {"content-type":"text/plain","date":"...","connection":"...","transfer-encoding":"chunked"}
响应体块 BODY CHUNK: Hello World!
--- 响应完成 Response Complete ---
Hello World!
响应中没有更多数据 No more data in response.

验证服务器输出。你会在 server.js 的终端中看到另一条日志消息,表明接收到了来自 client.js 的请求。

尽管 http 模块是基础,但构建复杂的 Web 应用通常会使用 Express、Koa 或 Fastify 等框架,这些框架为路由、中间件(middleware)、请求/响应处理等提供了抽象和实用工具。