# 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進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。