Node.js 服务器开发:处理 POST 请求数据

作者:星河

时间:2026-10-28

浏览:327

本文详解 Node.js 中处理 POST 请求的完整流程。通过构建包含表单的 HTML 页面,利用 data 和 end 事件异步接收数据块,并将 POST 数据传递至路由和处理程序。最后演示如何使用 querystring 模块解析表单字段,实现非阻塞的数据处理。

文章目录

Node.js 服务器开发:处理 POST 请求数据

此前的服务器功能较为单一,缺乏实际应用场景。接下来,我们将逐步实现具有实用价值的服务器功能。

我们的目标是:允许用户选择并上传文件,随后在浏览器中查看已上传的文件内容。

首先,我们需要提供一个文本输入区域(textarea),供用户输入内容,并通过 POST 请求将数据提交至服务器。

我们在 start 事件处理器中添加相关代码,并对 requestHandlers.js 进行如下修改:

具体代码如下:

function start(response) {
console.log("Request handler 'start' was called.");
var body = '<html>'+ '<head>'+
'<meta http-equiv="Content-Type" content="text/html; '+
'charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" method="post">'+
'<textarea name="text" rows="20" cols="60"></textarea>'+
'<input type="submit" value="Submit text" />'+
'</form>'+
'</body>'+
'</html>';
response.writeHead(200, {"Content-Type": "text/html"});
response.write(body);
response.end();
}
function upload(response) {
console.log("Request handler 'upload' was called.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("Hello Upload");
response.end();
}
exports.start = start;
exports.upload = upload;

通过在浏览器中访问 http://localhost:8888/start 即可看到上述效果。

接下来,我们需要实现当用户提交表单时,触发 /upload 请求处理程序来处理 POST 请求。

为了确保整个过程非阻塞,Node.js 会将 POST 数据拆分为多个小数据块,并通过触发特定事件将这些数据块传递给回调函数。这里涉及两个关键事件:data 事件(表示有新的小数据块到达)和 end 事件(表示所有数据接收完毕)。

我们通过在 request 对象上注册监听器(listener)来实现这一机制。这里的 request 对象是每次接收到 HTTP 请求时,都会传递给 onRequest 回调函数的对象。

我们将相关代码置于服务器端,并对 server.js 进行如下修改:

具体代码如下:

var http = require("http");
var url = require("url");
function start(route, handle) {
function onRequest(request, response) {
var postData = "";
var pathname = url.parse(request.url).pathname;
console.log("Request for " + pathname + " received.");
request.setEncoding("utf8");
request.addListener("data", function(postDataChunk) {
postData += postDataChunk;
console.log("Received POST data chunk '"+ postDataChunk + "'.");
  });
request.addListener("end", function() {
route(handle, pathname, response, postData);
  });
 }
http.createServer(onRequest).listen(8888);
console.log("Server has started.");
}
exports.start = start;

上述代码主要执行三项操作:首先,设置接收数据的编码格式为 UTF-8;其次,注册“data”事件的监听器,用于收集每次接收到的新数据块,并将其赋值给 postData 变量;最后,将请求路由的调用移至 end 事件处理程序中,以确保仅在所有数据接收完毕后触发一次路由,并将 POST 数据传递给请求路由,以便请求处理程序能够使用这些数据。

接下来,在 /upload 页面展示用户输入的内容。

我们来修改 router.js:

具体代码如下:

function route(handle, pathname, response, postData) {
console.log("About to route a request for " + pathname);
if (typeof handle[pathname] === 'function') {
handle[pathname](response, postData);
} else {
console.log("No request handler found for " + pathname);
response.writeHead(404, {"Content-Type": "text/plain"});
response.write("404 Not found");
response.end();
 }
}
exports.route = route;

随后,在 requestHandlers.js 中,我们将数据包含在对 upload 请求的响应中:

具体代码如下:

function start(response, postData) {
console.log("Request handler 'start' was called.");
var body = '<html>'+
'<head>'+
'<meta http-equiv="Content-Type" content="text/html; '+
'charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" method="post">'+
'<textarea name="text" rows="20" cols="60"></textarea>'+
'<input type="submit" value="Submit text" />'+
'</form>'+
'</body>'+
'</html>';
response.writeHead(200, {"Content-Type": "text/html"});
response.write(body);
response.end();
}
function upload(response, postData) {
console.log("Request handler 'upload' was called.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("You've sent: " + postData);
response.end();
}
exports.start = start;
exports.upload = upload;

最后一步:目前我们将请求的整个消息体传递给了请求路由和处理程序。实际上,我们只应将 POST 数据中感兴趣的部分传递给它们。在本例中,我们感兴趣的仅是 text 字段。

我们可以使用此前介绍过的 querystring 模块来实现这一目标:

具体代码如下:

var querystring = require("querystring");
function start(response, postData) {
console.log("Request handler 'start' was called.");
var body = '<html>'+
'<head>'+
'<meta http-equiv="Content-Type" content="text/html; '+
'charset=UTF-8" />'+
'</head>'+
'<body>'+
'<form action="/upload" method="post">'+
'<textarea name="text" rows="20" cols="60"></textarea>'+
'<input type="submit" value="Submit text" />'+
'</form>'+
'</body>'+
'</html>';
response.writeHead(200, {"Content-Type": "text/html"});
response.write(body);
response.end();
}
function upload(response, postData) {
console.log("Request handler 'upload' was called.");
response.writeHead(200, {"Content-Type": "text/plain"});
response.write("You've sent the text: "+ querystring.parse(postData).text);
response.end();
}
exports.start = start;
exports.upload = upload;

至此,关于处理 POST 数据的全部内容已介绍完毕。

下一节,我们将实现图片上传的功能。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章