如何在node.js中处理POST请求

嗨,我是Nodejs的新手目前我试图用node.js处理post请求我写了一个名为server.js的java脚本文件,它在浏览器上显示一个表单。 我想要使​​用表单值并将其张贴在HTML中。 对于示例窗体包含用户名,存储库,分支和一个提交button,所以我想填写表单后,当用户提交使用提交button,那么他应该能够看到这些值的HTML方面。

my server. js code is : var http = require('http'); http.createServer(function (request, response) { response.writeHead(200, {'Content-Type': 'text/html'}); response.end('<html><body>' + '<h1>XYZ Repository Commit Monitor</h1>' + '<form method="post" action="." 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>'); }).listen(8124); console.log('Server running at http://127.0.0.1:8124/'); 

现在我想处理这个post请求,并在用户填写表单并提交之后以html表单呈现数据。

我将使用您提供的代码,并提供比您的问题中涵盖的内容更全面的答案,以适应“遥远的未来”中的人们。 我也会提供一个使用“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的内置“查询string”模块来parsing实际的表单数据。

 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) { 

(我通常把这个函数的参数缩短为“req”和“res”,但这只是我的偏好。)

  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") { 

否则,如果你的访问者在你的服务器上指向一个POST,很可能他们已经提交了以前的GET请求检索到的表单。

  if (request.url === "/inbound") { 

在这里,我们正在监听叫做“/ 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请求可以作为来自客户端浏览器的多部分消息发送。 在某种forms中,只要有一些variables小的东西,就不会看到这一点,但随着您处理数据量的增加,您将看到这一点。 如果你仔细观察,你还会看到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的性质,这些variables名称是CASE SENSITIVE(例如“UserName”而不是“username”)。 当然,你可以用这个数据做任何你想要的事(记住Node的事件循环和asynchronous特性)。

  } 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()语句的底部包含了一个catch-all,它向客户端发送一个通用的404“未find”回复给我们尚未处理的任何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); 

现在我们刚刚完成了代码,包括一些代码来处理奇怪方法的请求。 有几件事我没有解决(function结构,空表格数据等),但确实有很多方法来实现你的目标。 正如我多年前曾经说过的CS教授之一,有很多方法可以编程,很容易看出谁在作弊。

我希望你(和其他任何人)可以看到,使用其内置模块而不是依靠诸如Express之类的外部第三方库,在Node中做事情并不是一些深奥或者甚至是稍微困难的过程。 这些图书馆在世界上占有一席之地,但不要追随牛群:对你的代码做出明智的决定,因为在这一天结束的时候,你是负责它的人(而不是堆栈溢出的人)。

如果您正在寻找基于承诺的HTTP客户端

 const axios = require('axios'); axios.post('/user', { firstName: 'Fred', lastName: 'Flintstone' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); 

url: https : //www.npmjs.com/package/axios