Node.js http 模块
Node.js 的 http
模块是 Node.js 内置的核心模块之一,它允许开发者创建 HTTP 服务器和客户端。通过这个模块,我们可以轻松地处理 HTTP 请求和响应,构建 Web 应用程序或 API 服务。
http
模块提供了创建服务器和发起 HTTP 请求的能力,是构建 Web 应用的基础。它支持 HTTP/1.1 协议,并提供了丰富的 API 来处理各种 HTTP 相关的操作。
创建 HTTP 服务器
使用 http
模块创建服务器非常简单,下面是一个最基本的示例:
实例
const http = require('http');
// 创建 HTTP 服务器
const server = http.createServer((req, res) => {
// 设置响应头
res.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据
res.end('Hello, World!\n');
});
// 监听 3000 端口
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
// 创建 HTTP 服务器
const server = http.createServer((req, res) => {
// 设置响应头
res.writeHead(200, {'Content-Type': 'text/plain'});
// 发送响应数据
res.end('Hello, World!\n');
});
// 监听 3000 端口
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
代码解析
require('http')
- 导入 Node.js 的 http 模块http.createServer()
- 创建一个 HTTP 服务器实例- 回调函数
(req, res) => {...}
- 处理每个 HTTP 请求req
- 请求对象,包含客户端发来的请求信息res
- 响应对象,用于向客户端发送响应
res.writeHead()
- 设置响应头res.end()
- 结束响应并发送数据server.listen()
- 启动服务器监听指定端口
处理 HTTP 请求
HTTP 服务器需要能够处理不同类型的请求,下面我们来看如何解析请求信息:
实例
const http = require('http');
const server = http.createServer((req, res) => {
// 获取请求方法、URL 和请求头
const { method, url, headers } = req;
// 记录请求信息
console.log(`收到 ${method} 请求,路径: ${url}`);
console.log('请求头:', headers);
// 根据请求方法处理
if (method === 'GET') {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('这是一个 GET 请求\n');
} else if (method === 'POST') {
let body = '';
// 收集 POST 数据
req.on('data', chunk => {
body += chunk;
});
// 数据接收完毕
req.on('end', () => {
console.log('POST 数据:', body);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('数据已接收\n');
});
} else {
res.writeHead(405, {'Content-Type': 'text/plain'});
res.end('方法不允许\n');
}
});
server.listen(3000);
const server = http.createServer((req, res) => {
// 获取请求方法、URL 和请求头
const { method, url, headers } = req;
// 记录请求信息
console.log(`收到 ${method} 请求,路径: ${url}`);
console.log('请求头:', headers);
// 根据请求方法处理
if (method === 'GET') {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('这是一个 GET 请求\n');
} else if (method === 'POST') {
let body = '';
// 收集 POST 数据
req.on('data', chunk => {
body += chunk;
});
// 数据接收完毕
req.on('end', () => {
console.log('POST 数据:', body);
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('数据已接收\n');
});
} else {
res.writeHead(405, {'Content-Type': 'text/plain'});
res.end('方法不允许\n');
}
});
server.listen(3000);
请求对象 (req) 常用属性
req.method
: HTTP 请求方法 (GET, POST, PUT, DELETE 等)req.url
: 请求的 URL 路径req.headers
: 请求头对象req.httpVersion
: HTTP 协议版本
响应对象 (res) 常用方法
res.writeHead(statusCode, headers)
: 设置响应状态码和头res.write(data)
: 写入响应体res.end([data])
: 结束响应,可选发送最后的数据res.setHeader(name, value)
: 设置响应头
发起 HTTP 请求
http
模块不仅可以创建服务器,还可以作为客户端发起 HTTP 请求:
实例
const http = require('http');
// 发起 GET 请求
http.get('http://jsonplaceholder.typicode.com/posts/1', (res) => {
let data = '';
// 接收数据
res.on('data', (chunk) => {
data += chunk;
});
// 数据接收完成
res.on('end', () => {
console.log('响应数据:', JSON.parse(data));
});
}).on('error', (err) => {
console.error('请求出错:', err);
});
// 发起 GET 请求
http.get('http://jsonplaceholder.typicode.com/posts/1', (res) => {
let data = '';
// 接收数据
res.on('data', (chunk) => {
data += chunk;
});
// 数据接收完成
res.on('end', () => {
console.log('响应数据:', JSON.parse(data));
});
}).on('error', (err) => {
console.error('请求出错:', err);
});
发起 POST 请求
实例
const http = require('http');
// 请求选项
const options = {
hostname: 'jsonplaceholder.typicode.com',
port: 80,
path: '/posts',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
// 创建请求
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('响应:', JSON.parse(data));
});
});
// 处理错误
req.on('error', (err) => {
console.error('请求出错:', err);
});
// 写入请求数据
const postData = JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
});
req.write(postData);
req.end();
// 请求选项
const options = {
hostname: 'jsonplaceholder.typicode.com',
port: 80,
path: '/posts',
method: 'POST',
headers: {
'Content-Type': 'application/json',
}
};
// 创建请求
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('响应:', JSON.parse(data));
});
});
// 处理错误
req.on('error', (err) => {
console.error('请求出错:', err);
});
// 写入请求数据
const postData = JSON.stringify({
title: 'foo',
body: 'bar',
userId: 1
});
req.write(postData);
req.end();
实际应用场景
1. 创建 RESTful API
实例
const http = require('http');
const server = http.createServer((req, res) => {
const { method, url } = req;
// 简单路由处理
if (method === 'GET' && url === '/api/users') {
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify([{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}]));
} else if (method === 'POST' && url === '/api/users') {
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => {
const newUser = JSON.parse(body);
// 这里可以保存到数据库
res.writeHead(201, {'Content-Type': 'application/json'});
res.end(JSON.stringify({id: Date.now(), ...newUser}));
});
} else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('Not Found\n');
}
});
server.listen(3000);
const server = http.createServer((req, res) => {
const { method, url } = req;
// 简单路由处理
if (method === 'GET' && url === '/api/users') {
res.writeHead(200, {'Content-Type': 'application/json'});
res.end(JSON.stringify([{id: 1, name: 'Alice'}, {id: 2, name: 'Bob'}]));
} else if (method === 'POST' && url === '/api/users') {
let body = '';
req.on('data', chunk => body += chunk);
req.on('end', () => {
const newUser = JSON.parse(body);
// 这里可以保存到数据库
res.writeHead(201, {'Content-Type': 'application/json'});
res.end(JSON.stringify({id: Date.now(), ...newUser}));
});
} else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('Not Found\n');
}
});
server.listen(3000);
2. 代理服务器
实例
const http = require('http');
const proxy = http.createServer((clientReq, clientRes) => {
// 向目标服务器发起请求
const options = {
hostname: 'example.com',
port: 80,
path: clientReq.url,
method: clientReq.method,
headers: clientReq.headers
};
const proxyReq = http.request(options, (proxyRes) => {
// 将目标服务器的响应转发给客户端
clientRes.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(clientRes);
});
// 转发客户端请求体
clientReq.pipe(proxyReq);
});
proxy.listen(8080);
const proxy = http.createServer((clientReq, clientRes) => {
// 向目标服务器发起请求
const options = {
hostname: 'example.com',
port: 80,
path: clientReq.url,
method: clientReq.method,
headers: clientReq.headers
};
const proxyReq = http.request(options, (proxyRes) => {
// 将目标服务器的响应转发给客户端
clientRes.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(clientRes);
});
// 转发客户端请求体
clientReq.pipe(proxyReq);
});
proxy.listen(8080);
最佳实践
- 错误处理:始终处理请求和响应中的错误事件
- 性能考虑:对于高并发应用,考虑使用连接池
- 安全性:
- 验证所有输入
- 设置适当的安全头
- 限制请求体大小防止 DOS 攻击
- 使用流:对于大文件传输,使用流式处理
- 考虑框架:对于复杂应用,考虑使用 Express、Koa 等框架
总结
Node.js 的 http
模块提供了构建网络应用的基础能力。虽然现在有许多更高级的框架可用,但理解 http
模块的工作原理对于任何 Node.js 开发者都至关重要。通过掌握这个核心模块,你可以更好地理解 Web 应用的工作机制,并能够根据需求构建自定义的解决方案。
点我分享笔记