Node.js 自诞生以来,凭借其非阻塞 I/O 和事件驱动的特性,迅速成为后端开发的重要工具。它不仅支持 JavaScript 在浏览器之外运行,还提供了丰富的内置模块,帮助开发者快速构建高性能的网络应用。
在本篇博客中,我们将深入讲解如何使用 Node.js 构建一个基础的 HTTP 静态资源服务器,并详细探讨:
require
与import
:CommonJS 与 ES6 模块化的区别- HTTP 协议的基本原理
- 如何创建和监听 HTTP 服务器
- 路由匹配与请求处理机制
- 文件系统操作(fs)与路径拼接(path)
- 错误处理与状态码设置
- URL 结构与查询参数理解
此外,我们还会对一段完整的 HTTP 服务器代码进行 详细解析,确保你掌握每一个细节。
🧩 什么是 Node.js?
Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行时环境,允许我们在服务器端执行 JavaScript 代码。
💡 JS 不仅是前端语言,在 Node.js 环境下,JavaScript 也可以作为后端语言在命令行中运行。
Node.js 适合中小型项目快速开发,尤其在高并发场景中表现优异,例如聊天服务器、API 接口服务等。
📦 Node.js 的模块化系统
模块化是现代编程语言的重要能力之一。Node.js 支持两种主要的模块化方案:
1. CommonJS(传统方式)
这是 Node.js 最早使用的模块化方案,使用 require()
来引入模块,以同步方式加载依赖。
const fs = require('fs');
2. ES6 Module(更先进的模块化方式)
ES6(ECMAScript 2015)提出了模块化标准,使用 import
和 export
实现模块化,更加符合现代 Web 开发趋势。
import fs from 'fs';
⚠️ 注意:Node.js 默认使用的是 CommonJS 模块化方式。如果要使用 ES6 模块化,需要将文件扩展名改为
.mjs
,或者在package.json
中设置"type": "module"
。
Node.js 正逐步向 CommonJS 说再见
随着 Node.js 22 版本的发布,官方对 ES6 模块的支持已经非常成熟。未来,Node.js 将更倾向于推荐使用 ES6 模块化方案,CommonJS 虽然仍会支持,但不再是首选。
🛠 创建 HTTP 服务器
Node.js 提供了内置的 http
模块,可以轻松创建 HTTP 服务器。
使用 CommonJS 方式创建服务器
const http = require('http');
const server = http.createServer((req, res) => {
res.end('Hello HTTP Server');
});
server.listen(8080);
使用 ES6 Module 方式创建服务器(需保存为 .mjs 文件)
// server.mjs
import http from 'http';
const server = http.createServer((req, res) => {
res.end('Hello HTTP Server (ES6)');
});
server.listen(1234);
✅ 小贴士:使用
node server.mjs
命令运行 ES6 模块化代码。
🌐 端口、进程与 IP 地址的关系
- IP 地址:标识网络中的某台设备,例如本地测试常用的
127.0.0.1
。 - 域名:如
localhost
,通常映射到127.0.0.1
。 - 端口:每个端口对应一个服务或进程,例如:
3306
→ MySQL 数据库8080
→ 自定义 HTTP 服务
- 一台设备可以同时运行多个服务,监听不同的端口。
⚠️ 建议避免使用特殊端口(如 0~1023),这些端口通常被操作系统保留使用。
🏗️ 构建静态资源服务器详解
我们的目标是搭建一个能响应 HTML、CSS、JS 等静态资源的服务器。
所需模块介绍
模块 | 功能 |
---|---|
http | 创建 HTTP 服务器 |
fs | 文件系统操作,读取文件内容 |
path | 处理路径拼接问题 |
示例目录结构
project-root/
├── public/
│ ├── index.html
│ ├── style.css
│ └── script.js
└── server.js
📜 完整代码解析
下面是对代码的完整解析,包含每一部分的功能说明:
// 引入 Node.js 内置的核心模块
const http = require('http'); // 用于创建 HTTP 服务器
const fs = require('fs'); // 用于读写文件系统
const path = require('path'); // 用于处理路径拼接问题
// 创建 HTTP 服务器实例
const server = http.createServer((req, res) => {
// 请求方法 + URL 组成路由
if (req.method === 'GET' && (req.url === '/' || req.url === '/index.html')) {
// 拼接文件路径,确保兼容不同操作系统
const filePath = path.join(__dirname, 'public', 'index.html');
// 异步读取文件内容
fs.readFile(filePath, (err, content) => {
if (err) {
// 发生错误时返回 500 服务器内部错误
res.writeHead(500);
res.end('Server Error');
return;
}
// 成功读取文件后返回 200 状态码和 HTML 内容
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content);
});
}
// 处理 /style.css 请求
else if (req.method === 'GET' && req.url === '/style.css') {
const filePath = path.join(__dirname, 'public', 'style.css');
fs.readFile(filePath, (err, content) => {
if (err) {
res.writeHead(500);
res.end('Server Error');
return;
}
// 返回 CSS 文件,设置 Content-Type 为 text/css
res.writeHead(200, { 'Content-Type': 'text/css' });
res.end(content);
});
}
// 处理 /script.js 请求
else if (req.method === 'GET' && req.url === '/script.js') {
const filePath = path.join(__dirname, 'public', 'script.js');
fs.readFile(filePath, (err, content) => {
if (err) {
res.writeHead(500);
res.end('Server Error');
return;
}
// 返回 JS 文件,设置 Content-Type 为 text/javascript
res.writeHead(200, { 'Content-Type': 'text/javascript' });
res.end(content);
});
}
// 其他请求返回 404
else {
// 对于不支持的路径,返回 404 Not Found
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Not Found');
}
});
// 启动服务器并监听 8080 端口
server.listen(8080, () => {
console.log('Server is running on http://localhost:8080');
});
🔍 关于 URL 结构的说明
完整的 URL 包含以下几个部分:
http://localhost:8080/style.css?a=1&b=2
↑ ↑ ↑ ↑ ↑
协议 域名 端口 路径 查询参数
- 协议(Protocol):
http
或https
- 域名(Domain):如
localhost
,代表本地机器 - 端口(Port):如
8080
- 路径(Path):如
/style.css
- 查询字符串(Query String):如
?a=1&b=2
🧱 后端的本质:资源的定位与响应
HTTP 是一种“请求-响应”协议。客户端通过 URL 发送请求,服务器根据 Method + URL 定位资源,并返回相应的内容。
在本例中,我们实现了最基本的“静态资源服务”,也就是将服务器上的文件原样返回给客户端。
🛡 错误处理的重要性
5xx
系列状态码表示服务器错误,如500 Internal Server Error
。- 我们在每次读取文件时都加入了错误判断逻辑,保证即使发生异常,也能返回友好的提示信息,而不是让客户端陷入等待。
📲 启动服务器并访问页面
- 确保你的项目结构正确,且
public/
目录下包含对应的 HTML、CSS、JS 文件。 - 在终端执行以下命令启动服务器:
node server.js
- 打开浏览器访问:
http://localhost:8080
你将看到你的首页内容,并成功加载 CSS 和 JS 文件。
📚 总结
本文全面讲解了如何使用 Node.js 构建一个简单的 HTTP 静态资源服务器,涵盖以下核心知识点:
✅ Node.js 是什么?
✅ CommonJS 与 ES6 模块化的区别
✅ 如何创建 HTTP 服务器
✅ 模块化方案的选择(.mjs
文件)
✅ 静态资源服务的工作原理
✅ 路由匹配与请求处理
✅ 内容类型(Content-Type)设置
✅ 错误处理机制
✅ URL 结构解析
✅ 端口、进程、线程之间的关系
如果你喜欢这篇文章,欢迎点赞、收藏并分享给更多想入门 Node.js 的朋友!
📌 最终提醒:如果你希望尝试 ES6 模块化,请将文件保存为 .mjs
格式,并使用最新版本的 Node.js(建议 v22+)进行测试。