Node.js HTTP模块详解:创建服务器、响应请求与客户端请求
Node.js HTTP模块详解:创建服务器、响应请求与客户端请求
Node.js 的 http
模块是 Node.js 核心模块之一,它允许你创建 HTTP 服务器和客户端。以下是一些关键知识点和代码示例:
1. 创建 HTTP 服务器
使用 http.createServer()
方法可以创建一个新的 HTTP 服务器实例。这个方法接受一个回调函数,该函数在服务器接收到请求时被调用,参数为 req
(请求对象)和 res
(响应对象)。
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Hello World\n');
});
server.listen(3000, () => {
console.log(`服务器运行在 http://localhost:3000/`);
});
2. 响应方法
Node.js 的 http
模块提供了多种方法来响应 HTTP 请求。以下是 http.ServerResponse
对象的一些常用方法及其作用:
-
writeHead(statusCode, [reasonPhrase], [headers]):
- 作用:发送一个 HTTP 响应头到客户端。
statusCode
是状态码,reasonPhrase
是可选的状态短语(例如:“OK”),headers
是一个包含头部字段的对象。 - 示例:
res.writeHead(200, { 'Content-Type': 'text/plain' });
- 作用:发送一个 HTTP 响应头到客户端。
-
write(chunk, [encoding]):
- 作用:发送一个 HTTP 响应体的片段。
chunk
是要发送的数据块,encoding
是数据的编码,默认为'utf8'
。 - 示例:
res.write('Hello, '); res.write('World!', 'utf8');
- 作用:发送一个 HTTP 响应体的片段。
-
end([data], [encoding]):
- 作用:发送 HTTP 响应体的最后一个片段,并关闭连接。如果提供了
data
,则会先发送这个数据。 - 示例:
res.end('This is the end of the response.');
- 作用:发送 HTTP 响应体的最后一个片段,并关闭连接。如果提供了
-
setHeader(name, value):
- 作用:设置响应头字段
name
的值为value
。 - 示例:
res.setHeader('Content-Type', 'application/json');
- 作用:设置响应头字段
-
getHeader(name):
- 作用:返回响应头字段
name
的值。 - 示例:
const contentType = res.getHeader('Content-Type');
- 作用:返回响应头字段
-
removeHeader(name):
- 作用:移除响应头字段
name
。 - 示例:
res.removeHeader('Content-Type');
- 作用:移除响应头字段
-
addTrailers(headers):
- 作用:添加 HTTP 尾部字段,这些字段在响应体之后发送。
- 示例:
res.addTrailers({ 'Content-MD5': '7895bf4e1c23b21b' });
-
flush():
- 作用:刷新响应体缓冲区,发送任何缓冲的数据到客户端。
- 示例:
res.flush();
-
finish():
- 作用:结束响应。如果响应体已经发送完毕,这个方法没有效果。如果响应体还在发送中,这个方法会发送剩余的数据。
- 示例:
res.finish();
-
setTimeout(msecs, callback):
- 作用:设置响应的超时时间。如果响应在
msecs
毫秒内没有结束,那么响应将被自动结束。 - 示例:
res.setTimeout(3000, () => { console.log('Response timed out'); });
- 作用:设置响应的超时时间。如果响应在
-
destroy(error):
- 作用:销毁流,这将发送一个 RST 包到 TCP 层,立即关闭连接。
- 示例:
res.destroy(new Error('Something went wrong'));
这些方法提供了控制 HTTP 响应的灵活性,允许开发者根据需要发送不同类型的响应。在实际应用中,你可能会根据业务逻辑和客户端的需求来选择使用这些方法。
3. 请求方法
在Node.js中,http
模块提供了request
方法来发送客户端请求到服务器。以下是http.request
方法的一些常用方式:
- 基本请求
const http = require('http');
const options = {
hostname: 'www.example.com',
port: 80,
path: '/path',
method: 'GET'
};
const req = http.request(options, (res) => {
console.log(`状态码: ${res.statusCode}`);
res.on('data', (chunk) => {
console.log(`收到数据块: ${chunk}`);
});
res.on('end', () => {
console.log('响应结束');
});
});
req.on('error', (e) => {
console.error(`请求遇到问题: ${e.message}`);
});
// 结束请求
req.end();
- 发送POST请求
const http = require('http');
const querystring = require('querystring');
const postData = querystring.stringify({
key1: 'value1',
key2: 'value2'
});
const options = {
hostname: 'www.example.com',
port: 80,
path: '/path',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': Buffer.byteLength(postData)
}
};
const req = http.request(options, (res) => {
// 处理响应
});
req.on('error', (e) => {
// 处理请求错误
});
req.write(postData);
req.end();
- 发送JSON数据
const http = require('http');
const JSON.stringify;
const data = {
key1: 'value1',
key2: 'value2'
};
const options = {
hostname: 'www.example.com',
port: 80,
path: '/path',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(JSON.stringify(data))
}
};
const req = http.request(options, (res) => {
// 处理响应
});
req.on('error', (e) => {
// 处理请求错误
});
req.write(JSON.stringify(data));
req.end();
- 使用GET参数
const http = require('http');
const querystring = require('querystring');
const params = {
key1: 'value1',
key2: 'value2'
};
const options = {
hostname: 'www.example.com',
port: 80,
path: `/path?${querystring.stringify(params)}`,
method: 'GET'
};
const req = http.request(options, (res) => {
// 处理响应
});
req.on('error', (e) => {
// 处理请求错误
});
req.end();
- 处理重定向
const http = require('http');
let redirectCount = 0;
const options = {
hostname: 'www.example.com',
port: 80,
path: '/path',
method: 'GET'
};
const req = http.request(options, (res) => {
if (res.statusCode === 301 || res.statusCode === 302) {
if (redirectCount < 10) {
redirectCount++;
const location = res.headers.location;
options.path = location;
const newReq = http.request(options, (res) => {
// 处理响应
});
newReq.end();
} else {
console.log('Too many redirects');
}
} else {
// 处理响应
}
});
req.on('error', (e) => {
// 处理请求错误
});
req.end();
这些示例展示了如何使用Node.js的http
模块发送不同类型的HTTP请求,包括基本的GET请求、POST请求、发送JSON数据、处理GET参数和自动处理重定向。
4. 处理 POST 请求
对于 POST 请求,你可以监听请求对象的 data
和 end
事件来处理请求体中的数据。
const http = require('http');
const server = http.createServer((req, res) => {
if (req.method === 'POST' && req.url === '/submit') {
let body = '';
req.on('data', chunk => {
body += chunk.toString();
});
req.on('end', () => {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(`Received data: ${body}`);
});
} else {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('404 Not Found');
}
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
5. Http状态码
在Node.js的http
模块中,设置响应头和状态码是通过http.ServerResponse
对象的方法writeHead
来完成的。以下是如何设置响应头和状态码的示例:
const http = require('http');
const server = http.createServer((req, res) => {
// 设置状态码为200(OK),并设置响应头
res.writeHead(200, {
'Content-Type': 'text/plain', // mime类型
'Custom-Header': 'Custom Value'
});
// 发送响应体
res.end('Hello, World!');
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
状态码的类型
HTTP状态码分为几种类型,每种类型表示不同的响应类别:
-
1xx(信息性状态码):表示接收到的请求正在处理中。
100 Continue
:表明客户端可以继续发送请求体。101 Switching Protocols
:服务器根据客户端的请求切换到了不同的协议。
-
2xx(成功状态码):表示请求已成功被服务器接收、理解、并接受。
200 OK
:请求成功。201 Created
:请求成功,并且服务器创建了新的资源。202 Accepted
:请求已被接受,但未被执行。
-
3xx(重定向状态码):表示需要进一步操作才能完成请求。
301 Moved Permanently
:请求的资源已被永久移动到新位置。302 Found
:请求的资源临时移动到另一个URI。304 Not Modified
:如果请求的资源未修改,可以返回此状态码,无需再次发送资源内容。
-
4xx(客户端错误状态码):表示请求包含错误或无法被服务器理解。
400 Bad Request
:服务器无法理解请求,请求无效或格式错误。401 Unauthorized
:请求需要用户的身份认证。403 Forbidden
:服务器理解请求,但是拒绝执行。404 Not Found
:服务器找不到请求的资源。
-
5xx(服务器错误状态码):表示服务器在处理请求的过程中发生了错误。
500 Internal Server Error
:服务器遇到了一个预料之外的情况,导致无法完成请求。501 Not Implemented
:服务器不支持请求的功能,无法完成请求。503 Service Unavailable
:服务器目前无法处理请求,可能是过载或停机维护。
状态码是HTTP协议的核心部分,它们为客户端提供了请求处理结果的标准化信息。正确使用状态码可以帮助客户端更好地理解服务器响应的含义,并据此进行适当的操作。
6. MIME类型
MIME(Multipurpose Internet Mail Extensions,多用途互联网邮件扩展)类型,也称为媒体类型,是一种标准,用于定义文件的格式和类型。在HTTP协议中,MIME类型用于告诉浏览器或接收端如何处理传输的数据。每个MIME类型由两部分组成:类型和子类型,中间用斜杠(/)分隔。
以下是一些常见的MIME类型及其描述:
-
Text-based MIME types:
text/html
:HTML文档。text/css
:层叠样式表(CSS)。text/javascript
:JavaScript代码。text/plain
:纯文本文件。text/xml
:XML文档。
-
Image MIME types:
image/gif
:GIF图片。image/jpeg
:JPEG图片。image/png
:PNG图片。image/svg+xml
:SVG矢量图。
-
Audio MIME types:
audio/mpeg
:MP3音频文件。audio/wav
:WAV音频文件。audio/ogg
:OGG音频文件。
-
Video MIME types:
video/mpeg
:MPEG视频文件。video/mp4
:MP4视频文件。video/ogg
:OGG视频文件。
-
Application MIME types:
application/json
:JSON数据。application/xml
:XML数据。application/pdf
:PDF文档。application/zip
:ZIP压缩文件。application/javascript
:JavaScript代码(通常用于外链脚本)。
-
Font MIME types:
font/ttf
:TrueType字体。font/otf
:OpenType字体。font/woff
:Web Open Font Format。font/woff2
:Web Open Font Format 2.0。
-
Other MIME types:
multipart/form-data
:用于表单数据的编码类型。binary/octet-stream
:任意的二进制数据。application/octet-stream
:用于二进制文件,如可执行文件或字节流。
MIME类型在HTTP响应的Content-Type
头字段中指定,告诉浏览器如何处理接收到的数据。同样,在发送HTTP请求时,Accept
请求头字段可以包含客户端能够处理的MIME类型列表,这允许服务器根据客户端的能力返回合适的数据格式。
7. 处理 JSON 数据
Node.js 的 http
模块可以处理 JSON 格式的数据,以下代码展示了如何返回 JSON 响应:
const http = require('http');
const server = http.createServer((req, res) => {
const jsonResponse = {
message: 'Hello, World!',
status: 'success',
};
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify(jsonResponse));
});
server.listen(3000, () => {
console.log('Server running at http://localhost:3000/');
});
这些是 Node.js http
模块的一些基本知识点和代码示例,可以帮助你开始使用 Node.js 进行 HTTP 通信。