http 模块
原生 createServer、请求/响应、最小 JSON API。
http 模块
这一课你将能做到
- 用零依赖的
node:http起一个 HTTP 服务器并处理请求、返回响应 - 手工解析路径、查询参数和 POST 的 JSON 请求体
- 解释 req/res 是两条流,说清状态码与 Content-Type 的作用
为什么要学
Express、Koa 这些框架最终都是对 http 模块的封装。先用原生模块写一遍服务器,你才能回答:路由到底是什么?中间件在哪一层工作?express.json() 到底替你干了什么?
人话:http.createServer 就是 Node 帮你把 TCP 里的字节流翻译成「一个请求对象 req、一个响应对象 res」,剩下的路由判断、参数解析、状态码返回都要自己动手。这课写的每个手工环节,都会在下一课被 Express 一一「收编」——先手工再框架,框架对你就是透明的。
先建立图像
浏览器: GET /hello?name=Java
│ TCP 连接(默认 127.0.0.1:3000)
▼
┌─ http.createServer((req, res) => { ... }) ─┐
│ req: method / url / headers / body(流) │
│ res: setStatus / setHeader / write / end │
└─────────────────────────────────────────────┘
│
▼
浏览器收到: 状态码 200 + 响应头 + 响应体
一次请求的生命周期 = 建连接 → 回调拿到 req/res → 你处理 → res.end() → 关闭
req 和 res 本质都是流:req 是可读流(请求体一点一点到),res 是可写流(响应体一点一点发)。这解释了两件事:为什么 POST body 要监听事件来收,为什么大响应不用一次凑齐内存。
跟着做
步骤 1:最小服务器
新建 node-http 目录,npm init -y,新建 server.js:
// server.js
const http = require('node:http');
const server = http.createServer((req, res) => {
console.log('收到请求:', req.method, req.url);
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('hello from node http');
});
const PORT = 3000;
server.listen(PORT, () => {
console.log(`服务器已启动: http://localhost:${PORT}`);
});
node server.js
# 服务器已启动: http://localhost:3000
浏览器访问 http://localhost:3000,看到 hello from node http;终端会打印 收到请求: GET /。浏览器还会额外发一次 GET /favicon.ico,属正常现象。
按 Ctrl+C 停止。改了代码要手动重启(下一课的 nodemon / node --watch 解决这个)。
步骤 2:加路由与查询参数
升级 server.js,用 new URL() 解析请求:
// server.js
const http = require('node:http');
const server = http.createServer((req, res) => {
// 第二个参数是基准地址,用来把 req.url 解析成结构化对象
const url = new URL(req.url, `http://${req.headers.host}`);
const pathname = url.pathname; // /hello
const name = url.searchParams.get('name') ?? 'world';
if (pathname === '/hello') {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end(`hello, ${name}`);
return;
}
res.statusCode = 404;
res.setHeader('Content-Type', 'text/plain; charset=utf-8');
res.end('Not Found');
});
server.listen(3000, () => console.log('http://localhost:3000'));