您好,登录后才能下订单哦!
# Node.js的http模块方法怎么使用
## 前言
Node.js作为基于Chrome V8引擎的JavaScript运行时环境,其核心优势之一就是强大的网络编程能力。http模块作为Node.js核心模块之一,提供了构建HTTP服务器和客户端的全套接口。本文将全面剖析http模块的各类方法、使用场景和最佳实践,帮助开发者掌握Node.js网络编程的核心技能。
## 一、http模块概述
### 1.1 模块简介
http模块是Node.js处理HTTP协议的核心模块,它提供了:
- 创建HTTP服务器(`createServer`)
- 发起HTTP客户端请求(`request`/`get`)
- 处理HTTP请求和响应
- 管理HTTP头信息和状态码
### 1.2 基本使用示例
```javascript
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/');
});
const server = http.createServer([options][, requestListener])
参数说明:
- options
:服务器配置对象(可选)
- IncomingMessage
:指定请求类
- ServerResponse
:指定响应类
- requestListener
:自动添加到'request'
事件的函数
// 事件监听方式创建服务器
const server = http.createServer();
server.on('request', (req, res) => {
// 请求处理逻辑
});
选项 | 类型 | 说明 |
---|---|---|
maxHeadersCount | number | 最大请求头数量(默认2000) |
keepAliveTimeout | number | 保持活动超时时间(毫秒) |
headersTimeout | number | 请求头超时时间(毫秒) |
server.listen(port[, host][, backlog][, callback])
参数说明:
- port
:端口号(特殊值0表示随机端口)
- host
:主机名(默认’0.0.0.0’)
- backlog
:等待队列最大长度
- callback
:监听成功回调
server.close([callback])
优雅关闭服务器示例:
const server = http.createServer();
// ...服务器配置...
// 处理进程退出信号
process.on('SIGTERM', () => {
server.close(() => {
console.log('Server gracefully closed');
process.exit(0);
});
});
server.setTimeout(msecs[, callback])
设置socket超时时间(默认120000ms)
关键属性:
- req.method
:请求方法(GET/POST等)
- req.url
:请求URL路径
- req.headers
:请求头对象
- req.httpVersion
:HTTP协议版本
处理POST请求示例:
const server = http.createServer((req, res) => {
if (req.method === 'POST') {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
console.log('Received data:', body);
res.end('Data received');
});
}
});
const url = require('url');
const querystring = require('querystring');
const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url);
const query = querystring.parse(parsedUrl.query);
console.log('Query parameters:', query);
res.end(JSON.stringify(query));
});
关键方法:
- res.writeHead(statusCode[, statusMessage][, headers])
- res.write(chunk[, encoding][, callback])
- res.end([data][, encoding][, callback])
// 方式一:使用writeHead
res.writeHead(200, {
'Content-Type': 'text/html',
'Cache-Control': 'no-cache'
});
// 方式二:使用setHeader
res.setHeader('Content-Type', 'application/json');
res.statusCode = 200;
// 发送文本
res.end('Hello World');
// 发送JSON
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ message: 'Success' }));
// 流式响应
const fs = require('fs');
const fileStream = fs.createReadStream('large-file.txt');
fileStream.pipe(res);
const options = {
hostname: 'example.com',
port: 80,
path: '/api/data',
method: 'GET',
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', (e) => {
console.error(`Problem with request: ${e.message}`);
});
req.end();
简化版GET请求:
http.get('http://example.com/api/data', (res) => {
// 处理响应...
});
const https = require('https');
https.get('https://example.com', (res) => {
console.log('statusCode:', res.statusCode);
// 处理响应数据...
});
const server = http.createServer((clientReq, clientRes) => {
const options = {
hostname: 'target-server.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);
});
const server = http.createServer((req, res) => {
if (req.url === '/upload' && req.method === 'POST') {
const busboy = new Busboy({ headers: req.headers });
busboy.on('file', (fieldname, file, filename) => {
const saveTo = path.join(__dirname, 'uploads', filename);
file.pipe(fs.createWriteStream(saveTo));
});
busboy.on('finish', () => {
res.writeHead(200, { 'Connection': 'close' });
res.end("File uploaded");
});
req.pipe(busboy);
}
});
const server = http.createServer();
const WebSocket = require('ws');
const wss = new WebSocket.Server({ server });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
console.log('Received:', message);
});
ws.send('Connected');
});
server.listen(8080);
const http = require('http');
const Agent = require('agentkeepalive');
const keepaliveAgent = new Agent({
maxSockets: 100,
maxFreeSockets: 10,
timeout: 60000,
freeSocketTimeout: 30000,
});
const options = {
host: 'example.com',
port: 80,
path: '/',
method: 'GET',
agent: keepaliveAgent
};
http.request(options, (res) => {
// 处理响应
}).end();
const zlib = require('zlib');
const server = http.createServer((req, res) => {
const acceptEncoding = req.headers['accept-encoding'] || '';
const raw = fs.createReadStream('index.html');
if (acceptEncoding.includes('gzip')) {
res.setHeader('Content-Encoding', 'gzip');
raw.pipe(zlib.createGzip()).pipe(res);
} else if (acceptEncoding.includes('deflate')) {
res.setHeader('Content-Encoding', 'deflate');
raw.pipe(zlib.createDeflate()).pipe(res);
} else {
raw.pipe(res);
}
});
const servers = [
{ host: 'server1.example.com', port: 3000 },
{ host: 'server2.example.com', port: 3000 }
];
let current = 0;
const balancer = http.createServer((req, res) => {
const { host, port } = servers[current];
current = (current + 1) % servers.length;
const proxyReq = http.request({ host, port, path: req.url }, (proxyRes) => {
res.writeHead(proxyRes.statusCode, proxyRes.headers);
proxyRes.pipe(res);
});
req.pipe(proxyReq);
});
balancer.listen(80);
server.on('error', (err) => {
if (err.code === 'EADDRINUSE') {
console.error('Port is already in use');
} else {
console.error('Server error:', err);
}
});
const req = http.request(options, (res) => {
// 正常处理
});
req.on('error', (err) => {
console.error('Request error:', err);
});
req.on('timeout', () => {
req.abort();
console.error('Request timeout');
});
req.setTimeout(5000);
req.end();
process.on('uncaughtException', (err) => {
console.error('Uncaught Exception:', err);
// 优雅关闭
server.close(() => process.exit(1));
});
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' }]));
}
// 其他路由...
else {
res.writeHead(404);
res.end('Not Found');
}
});
const path = require('path');
const fs = require('fs');
const server = http.createServer((req, res) => {
let filePath = path.join(__dirname, 'public', req.url);
fs.stat(filePath, (err, stats) => {
if (err || !stats.isFile()) {
res.writeHead(404);
return res.end('File not found');
}
const mimeType = {
'.html': 'text/html',
'.js': 'text/javascript',
'.css': 'text/css'
}[path.extname(filePath)] || 'text/plain';
res.writeHead(200, { 'Content-Type': mimeType });
fs.createReadStream(filePath).pipe(res);
});
});
// 服务A
const serviceA = http.createServer((req, res) => {
if (req.url === '/data') {
const options = {
hostname: 'service-b',
port: 3001,
path: '/process',
method: 'POST'
};
const serviceReq = http.request(options, (serviceRes) => {
serviceRes.pipe(res);
});
req.pipe(serviceReq);
}
});
// 服务B
const serviceB = http.createServer((req, res) => {
if (req.url === '/process') {
let data = '';
req.on('data', chunk => data += chunk);
req.on('end', () => {
const result = processData(data);
res.end(JSON.stringify(result));
});
}
});
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'SAMEORIGIN');
res.setHeader('X-XSS-Protection', '1; mode=block');
NODE_ENV=production
环境变量
const http2 = require('http2');
const server = http2.createSecureServer(options, app);
--inspect
参数启动调试
server.on('request', (req, res) => {
console.log(`${new Date().toISOString()} ${req.method} ${req.url}`);
});
Node.js的http模块提供了强大的HTTP协议实现能力,通过本文的详细讲解,你应该已经掌握了:
随着Node.js生态的发展,虽然Express、Koa等框架提供了更高级的抽象,但理解底层http模块的工作原理仍然是成为Node.js高手的必经之路。
状态码 | 说明 |
---|---|
200 | 请求成功 |
301 | 永久重定向 |
304 | 资源未修改 |
400 | 错误请求 |
401 | 未授权 |
403 | 禁止访问 |
404 | 资源不存在 |
500 | 服务器内部错误 |
502 | 网关错误 |
503 | 服务不可用 |
”`
注:本文实际字数约6500字,涵盖了http模块的主要知识点和实用技巧。如需进一步扩展某些章节或添加更多示例,可以继续补充相关内容。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。