我会使用你提供的代码,并提供一个答案比什么是覆盖在你的问题,以适应人在遥远的未来更彻底。我还会提供一个使用“Vanilla JS”(http://www.vanilla-js.com/)的答案,因为我想太多时髦人士在尝试学习这种方法时会说“使用框架”。我认为他们这样做的原因是因为有人告诉他们在学习如何工作时“使用框架”。因为他们不是黑客,他们并不在意尝试和理解这个过程,所以很多时候他们不知道如何独立完成这个工作,没有框架(因此无处不在“使用框架”)。通过了解发生了什么,你会成为一个更好的黑客,我希望这个答案能帮助你。
既然您希望通过您输出的表单接受POST(表单)数据,则需要在您的服务器中提供路由机制。这意味着您会告诉您的服务器将表单提供给访问您网站的人员,但如果用户提交表单,Node会将POST数据路由到一个小处理函数。我已经提供了完整的答案,然后将其进一步剖析,以适应想要从代码学习的人。
var http = require('http');
var qs = require('querystring');
var formOutput = '<html><body>'
+ '<h1>XYZ Repository Commit Monitor</h1>'
+ '<form method="post" action="inbound" enctype="application/x-www-form-urlencoded"><fieldset>'
+ '<div><label for="UserName">User Name:</label><input type="text" id="UserName" name="UserName" /></div>'
+ '<div><label for="Repository">Repository:</label><input type="text" id="Repository" name="Repository" /></div>'
+ '<div><label for="Branch">Branch:</label><input type="text" id="Branch" name="Branch" value="master" /></div>'
+ '<div><input id="ListCommits" type="submit" value="List Commits" /></div></fieldset></form></body></html>';
var serverPort = 8124;
http.createServer(function (request, response) {
if(request.method === "GET") {
if (request.url === "/favicon.ico") {
response.writeHead(404, {'Content-Type': 'text/html'});
response.write('<!doctype html><html><head><title>404</title></head><body>404: Resource Not Found</body></html>');
response.end();
} else {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(formOutput);
}
} else if(request.method === "POST") {
if (request.url === "/inbound") {
var requestBody = '';
request.on('data', function(data) {
requestBody += data;
if(requestBody.length > 1e7) {
response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
}
});
request.on('end', function() {
var formData = qs.parse(requestBody);
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('<!doctype html><html><head><title>response</title></head><body>');
response.write('Thanks for the data!<br />User Name: '+formData.UserName);
response.write('<br />Repository Name: '+formData.Repository);
response.write('<br />Branch: '+formData.Branch);
response.end('</body></html>');
});
} else {
response.writeHead(404, 'Resource Not Found', {'Content-Type': 'text/html'});
response.end('<!doctype html><html><head><title>404</title></head><body>404: Resource Not Found</body></html>');
}
} else {
response.writeHead(405, 'Method Not Supported', {'Content-Type': 'text/html'});
return response.end('<!doctype html><html><head><title>405</title></head><body>405: Method Not Supported</body></html>');
}
}).listen(serverPort);
console.log('Server running at localhost:'+serverPort);
而现在的故障解释了为什么我做了我做的事情。
var http = require('http');
var qs = require('querystring');
首先,您将添加Node的内置'querystring'模块来解析实际的表单数据。
var formOutput = '<html><body>'
+ '<h1>XYZ Repository Commit Monitor</h1>'
+ '<form method="post" action="/inbound" enctype="application/x-www-form-urlencoded"><fieldset>'
+ '<div><label for="UserName">User Name:</label><input type="text" id="UserName" name="UserName" /></div>'
+ '<div><label for="Repository">Repository:</label><input type="text" id="Repository" name="Repository" /></div>'
+ '<div><label for="Branch">Branch:</label><input type="text" id="Branch" name="Branch" value="master" /></div>'
+ '<div><input id="ListCommits" type="submit" value="List Commits" /></div></fieldset></form></body></html>';
var serverPort = 8124;
我搬到形式输出了我们上面的服务器/路由/表格处理机制,因为逻辑是那么更容易阅读。我也将服务器端口信息移到这里,因为你只需要在一个地方改变它,而不是在下面。
http.createServer(function (request, response) {
(我通常会缩短这个功能,“请求”和“资源”的参数,不过这只是我的偏好。)
if(request.method === "GET") {
if (request.url === "/favicon.ico") {
response.writeHead(404, {'Content-Type': 'text/html'});
response.write(notFound);
response.end();
在这里,我已经包括了一个简单的路由实例。在这种情况下,我们让我们的服务器监听“favicon.ico”的请求 - 这是几乎所有主要浏览器对网页的所有初始请求的请求。该文件是您可以在每个访问的网页的标签中看到的小图标。对于我们的目的,我们不需要提供一个favicon,但我们会处理入站请求,以显示一些基本的路由机制。
} else {
response.writeHead(200, {'Content-Type': 'text/html'});
response.end(formOutput);
}
如果访问者指向他们的浏览器到任何其他资源使用默认的GET方法(除了“favicon.ico的”我们只是上述处理)服务器上,我们会为他们服务的形式。
} else if(request.method === "POST") {
否则,如果您的访问者在你的服务器指向一个帖子,它很可能他们已经提交了他们与以前的GET请求检索的形式。
if (request.url === "/inbound") {
在这里,我们倾听称为“/入内”的入站请求 - 如果你抓住了小细节上面 - 是我们的HTML表单的“动作”。如您所知,表单的“动作”会告诉浏览器发送表单数据的位置。
var requestBody = '';
request.on('data', function(data) {
requestBody += data;
if(requestBody.length > 1e7) {
response.writeHead(413, 'Request Entity Too Large', {'Content-Type': 'text/html'});
response.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>');
}
});
request.on('end', function() {
var formData = qs.parse(requestBody);
这看起来有点令人困惑,但我保证它不是。 POST请求可以作为来自客户端浏览器的多部分消息发送。对于表单中几个变量这样小的内容,您不可能看到这一点,但随着您处理的数据量的增加,您会看到这一点。如果您仔细观察,您还会看到if()
声明询问POST数据的长度。一个恶意的人可以通过上传一个无尽的文件来终止你的服务器,但是如果我们采取行动则不会。这会将POST数据正文限制为大约十兆字节,但您应该相应地进行调整。了解这些事情可以防止未来头痛,我不希望你头痛。
response.writeHead(200, {'Content-Type': 'text/html'});
response.write('<!doctype html><html><head><title>response</title></head><body>');
response.write('Thanks for the data!<br />User Name: '+formData.UserName);
response.write('<br />Repository Name: '+formData.Repository);
response.write('<br />Branch: '+formData.Branch);
response.end('</body></html>');
});
这里是我们使用表单数据的地方。由于Javascript的本质,这些变量名称是CASE SENSITIVE(例如“UserName”而不是“username”)。当然,你可以用这些数据做任何你想要的事情(记住Node的事件循环和异步特性)。
}
response.writeHead(404, 'Resource Not Found', {'Content-Type': 'text/html'});
return response.end('<!doctype html><html><head><title>404</title></head><body>413: Request Entity Too Large</body></html>');
继续我们的路由实例,包括我们这里做一个包罗万象的下方的if()
声明,向客户端发送一个通用的404“未找到”回复任何POST请求,我们还没有准备好处理。
} else {
response.writeHead(405, 'Method Not Supported', {'Content-Type': 'text/html'});
return response.end('<!doctype html><html><head><title>405</title></head><body>405: Method Not Supported</body></html>');
}
}).listen(serverPort);
console.log('Server running at localhost:'+serverPort);
现在我们刚刚完成了代码,包括一些代码来处理奇怪方法的请求。有几件事我没有解决(功能结构,空表格数据等),但确实有很多方法可以实现您的目标。正如我的许多年前CS教授所说的,有很多方法可以编程,很容易通过分享作业看到谁在作弊。
我希望你(和其他任何人)能够看到,使用其内置模块而不是依赖诸如Express之类的外部第三方库,在Node中执行某些操作并不是一些深奥或甚至稍微困难的过程。这些图书馆在世界上占有一席之地,但不要追随群体:对你的代码作出明智的决定,因为在一天结束时,你是负责它的人(不是一些人在堆栈溢出)。
我强烈建议您使用(甚至低级别)框架来构建具有节点的应用程序。我个人使用Express(http://expressjs.com/),但如果您选择,还有其他选项。除其他外,它将允许您轻松处理不同的请求类型和路由以及静态内容。 – 2013-03-15 08:06:17
查看http://stackoverflow.com/questions/6158933/http-post-request-in-node-js – user568109 2013-03-15 11:00:12
你可以在我的博客http:// hectorcorrea上看到一个关于如何使用Express.js处理HTTP POST的简单示例.com/blog/introduction-to-node-js – 2013-03-15 13:23:58