最简单的 HTTP 服务器
Node.js 内置了 http 模块,我们可以用它来创建一个最基本的服务器,这个服务器会监听一个端口,并对每个请求返回 "Hello, World!"。

代码 (server.js):
// 1. 导入 Node.js 内置的 'http' 模块
const http = require('http');
// 2. 定义服务器将要监听的端口号
const port = 3000;
// 3. 创建服务器
// createServer 方法接收一个回调函数,这个函数会在每次有请求进入时被调用
// 回调函数有两个参数:request (req) 和 response (res)
const server = http.createServer((req, res) => {
// 4. 设置响应头
// HTTP 状态码: 200 (表示成功)类型: text/plain (纯文本)
res.writeHead(200, { 'Content-Type': 'text/plain' });
// 5. 发送响应体并结束响应
res.end('Hello, World!\n');
});
// 6. 启动服务器,让它监听指定的端口
server.listen(port, () => {
// 7. 当服务器成功启动后,这个回调函数会被执行
console.log(`Server is running and listening on http://localhost:${port}`);
});
如何运行:
- 将以上代码保存为
server.js。 - 打开终端或命令行。
- 运行命令:
node server.js - 你会看到终端输出:
Server is running and listening on http://localhost:3000 - 打开浏览器,访问
http://localhost:3000,你将看到 "Hello, World!"。
代码深入解析
| 代码片段 | 说明 |
|---|---|
const http = require('http'); |
require 是 Node.js 的函数,用于引入模块。http 是 Node.js 核心模块,无需额外安装。 |
http.createServer((req, res) => { ... }); |
这是核心方法,它创建了一个新的服务器实例,并接收一个请求监听器(回调函数),每当有新的 HTTP 请求到达时,这个回调函数就会被执行。 |
req (Request 对象) |
代表客户端发来的 HTTP 请求,它包含了请求的所有信息, - req.method: 请求方法,如 'GET', 'POST'。- req.url: 请求的 URL 路径,如 /about。- req.headers: 请求头对象,包含如 'User-Agent', 'Accept' 等信息。 |
res (Response 对象) |
代表服务器将要发送给客户端的 HTTP 响应,我们通过这个对象来构建和发送响应。 - res.writeHead(statusCode, [statusMessage], [headers]): 发送一个响应头。statusCode 是 HTTP 状态码(如 200, 404, 500)。headers 是一个对象,包含响应头信息,如 Content-Type。- res.end([data], [encoding]): 结束响应,如果提供了 data,它会和之前通过 write() 或 writeHead() 写入的内容一起发送,这是发送响应的最后一个步骤。 |
server.listen(port, callback); |
让服务器开始在指定的 port 上监听客户端的连接,当服务器成功启动并准备好接收连接时,callback 函数会被执行。 |
处理不同的路由和请求方法
一个真实的服务器需要根据不同的 URL 和请求方法返回不同的内容,我们可以通过检查 req.method 和 req.url 来实现。
代码 (router.js):

const http = require('http');
const port = 3000;
const server = http.createServer((req, res) => {
// 获取请求方法和路径
const method = req.method;
const url = req.url;
// 设置响应头为 HTML,这样浏览器可以正确渲染
res.setHeader('Content-Type', 'text/html');
if (method === 'GET' && url === '/') {
// 首页
res.writeHead(200);
res.end('<h1>Welcome to the Home Page!</h1>');
} else if (method === 'GET' && url === '/about') {
// 关于页面
res.writeHead(200);
res.end('<h1>About Us</h1><p>This is a simple Node.js server.</p>');
} else if (method === 'POST' && url === '/submit-data') {
// 处理 POST 请求
let body = '';
req.on('data', chunk => {
body += chunk.toString(); // 将数据块拼接成字符串
});
req.on('end', () => {
res.writeHead(200);
res.end(`<h1>Received POST data:</h1><p>${body}</p>`);
});
} else {
// 404 Not Found
res.writeHead(404);
res.end('<h1>404 Not Found</h1><p>The page you are looking for does not exist.</p>');
}
});
server.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
说明:
- 我们使用
if/else if/else结构来匹配不同的(method, url)组合,这就是最简单的路由。 - 对于
POST请求,请求体(request body)不是一次性接收到的,而是以数据块(chunks)的形式流式传输过来的,我们需要监听req的data事件来收集数据块,并在end事件触发时(所有数据接收完毕)处理数据。 - 对于不存在的路径,我们返回
404 Not Found状态码。
从原生模块到框架
虽然用原生 http 模块可以构建服务器,但处理路由、中间件、静态文件等会变得非常繁琐和重复,社区诞生了许多优秀的 Web 框架,它们封装了底层细节,提供了更优雅、更强大的开发体验。
最流行的两个框架是 Express 和 Koa。
为什么使用框架?
- 路由管理:框架提供了清晰的路由定义方式(如
app.get(),app.post())。 - 中间件:框架的核心概念,允许你将请求处理函数模块化,可以处理日志、认证、解析请求体等。
- 模板引擎:轻松渲染动态 HTML 页面。
- 静态文件服务:轻松提供 CSS、JavaScript、图片等静态资源。
- 错误处理:提供统一的错误处理机制。
使用 Express 框架的例子
你需要安装 Express:

npm init -y # 初始化一个 package.json 文件 npm install express
代码 (app.js):
// 1. 导入 express 框架
const express = require('express');
const app = express(); // 创建一个 Express 应用实例
const port = 3000;
// 2. 使用中间件来解析 JSON 格式的请求体
// 这样我们就可以在 POST 请求中通过 req.body 获取数据
app.use(express.json());
// 3. 定义路由
// GET 请求到根路径
app.get('/', (req, res) => {
res.send('<h1>Welcome to the Express Home Page!</h1>');
});
// GET 请求到 /about 路径
app.get('/about', (req, res) => {
res.send('<h1>About Us (Express)</h1>');
});
// POST 请求到 /api/users 路径
app.post('/api/users', (req, res) => {
// 请求体已经被 express.json() 中间件解析好了
const newUser = req.body;
console.log('Received new user:', newUser);
res.status(201).json({ message: 'User created successfully!', user: newUser });
});
// 4. 404 处理中间件
// 这个中间件应该放在所有路由的后面
app.use((req, res) => {
res.status(404).send('<h1>404 - Page Not Found (Express)</h1>');
});
// 5. 启动服务器
app.listen(port, () => {
console.log(`Express server is running on http://localhost:${port}`);
});
对比原生 http 和 Express:
- 简洁性:Express 的路由定义 (
app.get()) 比原生if/else判断清晰得多。 - 中间件:
app.use(express.json())一行代码就解决了 POST 请求体解析的复杂问题。 - 响应方法:
res.send(),res.json()等方法简化了发送不同类型响应的过程。 - 状态码:
res.status(201).json(...) 设置状态码和发送响应结合得非常方便。
| 特性 | 原生 http 模块 |
Express 框架 |
|---|---|---|
| 易用性 | 较低,需要手动处理所有细节 | 高,提供了丰富的 API 和抽象 |
| 路由 | 手动 if/else 判断 req.method 和 req.url |
声明式,如 app.get('/path', handler) |
| 中间件 | 无内置支持,需自己实现 | 核心功能,用于模块化处理逻辑 |
| 请求/响应 | 手动调用 writeHead 和 end |
链式调用,如 res.status(200).json({}) |
| 适用场景 | 学习 Node.js 底层原理、构建极简服务 | 绝大多数 Web 应用,如 API、网站 |
建议:
- 初学者:从原生
http模块开始,可以帮助你深刻理解 Node.js 的 I/O 模型(事件驱动、非阻塞)和 HTTP 协议的工作原理。 - 实际开发:直接使用 Express 或 Koa 这样的框架,它们能让你更专注于业务逻辑,而不是重复造轮子,大大提高开发效率。
