如何在Node.js中提取POST数据?

如何提取表单数据( form[method="post"] )和从Node.js中的HTTP POST方法发送的file upload?

我读过文档,Googlesearch,什么都没发现。

 function (request, response) { //request.post???? } 

有图书馆还是黑客?

如果您使用Express (Node.js的高性能,高级Web开发),则可以这样做:

HTML:

 <form method="post" action="/"> <input type="text" name="user[name]"> <input type="text" name="user[email]"> <input type="submit" value="Submit"> </form> 

JavaScript的:

 app.use(express.bodyParser()); app.post('/', function(request, response){ console.log(request.body.user.name); console.log(request.body.user.email); }); 

2016年6月1日更新:

上面的方法现在不推荐使用:

 /** bodyParser.urlencoded(options) * Parses the text as URL encoded data (which is how browsers tend to send form data from regular forms set to POST) * and exposes the resulting object (containing the keys and values) on req.body */ app.use(bodyParser.urlencoded({ extended: true })); /**bodyParser.json(options) * Parses the text as JSON and exposes the resulting object on req.body. */ app.use(bodyParser.json()); app.post("/", function (req, res) { console.log(req.body.user.name) }); 

你可以使用querystring模块:

 var qs = require('querystring'); function (request, response) { if (request.method == 'POST') { var body = ''; request.on('data', function (data) { body += data; // Too much POST data, kill the connection! // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB if (body.length > 1e6) request.connection.destroy(); }); request.on('end', function () { var post = qs.parse(body); // use post['blah'], etc. }); } } 

现在,例如,如果您有一个名称为“ ageinput字段,则可以使用variablespost来访问它:

 console.log(post.age); 

一定要杀死连接,如果有人试图淹没你的RAM!

 var qs = require('querystring'); function (request, response) { if (request.method == 'POST') { var body = ''; request.on('data', function (data) { body += data; // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB if (body.length > 1e6) { // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUEST request.connection.destroy(); } }); request.on('end', function () { var POST = qs.parse(body); // use POST }); } } 

这里是一个非常简单的无框架封装基于其他答案和文章张贴在这里:

 var http = require('http'); var querystring = require('querystring'); function processPost(request, response, callback) { var queryData = ""; if(typeof callback !== 'function') return null; if(request.method == 'POST') { request.on('data', function(data) { queryData += data; if(queryData.length > 1e6) { queryData = ""; response.writeHead(413, {'Content-Type': 'text/plain'}).end(); request.connection.destroy(); } }); request.on('end', function() { request.post = querystring.parse(queryData); callback(); }); } else { response.writeHead(405, {'Content-Type': 'text/plain'}); response.end(); } } 

用法示例:

 http.createServer(function(request, response) { if(request.method == 'POST') { processPost(request, response, function() { console.log(request.post); // Use request.post here response.writeHead(200, "OK", {'Content-Type': 'text/plain'}); response.end(); }); } else { response.writeHead(200, "OK", {'Content-Type': 'text/plain'}); response.end(); } }).listen(8000); 

如果您将数据编码为JSON ,然后将其发送到Node.js,它会更干净。

 function (req, res) { if (req.method == 'POST') { var jsonString = ''; req.on('data', function (data) { jsonString += data; }); req.on('end', function () { console.log(JSON.parse(jsonString)); }); } } 

这里的很多答案不再是好的做法,也不解释任何事情,所以这就是我写这个的原因。

当调用http.createServer的callback函数时,服务器实际上收到了请求的所有头信息,但是可能还没有收到数据,所以我们必须等待。 http请求对象(一个http.IncomingMessage实例)实际上是一个可读的 stream 。 在可读stream中,每当有大块数据到达时, 就会发出一个data 事件 (假设您已经注册了一个callback),并且当所有块到达时都会发出end事件。 以下是您如何聆听事件的示例:

 http.createServer((request, response) => { console.log('Now we have a http message with headers but no data yet.'); request.on('data', chunk => { console.log('A chunk of data has arrived: ', chunk); }); request.on('end', () => { console.log('No more data'); }) }).listen(8080) 

如果你尝试这个,你会注意到这个块是缓冲区 。 如果你没有处理二进制数据,而需要使用string,我build议使用request.setEncoding方法,使stream发射string与给定的编码解释和正确处理多字节字符。

现在你可能对它自己的每个块都不感兴趣,所以在这种情况下你可能想要像这样缓冲它:

 http.createServer((request, response) => { const chunks = []; request.on('data', chunk => chunks.push(chunk)); request.on('end', () => { const data = Buffer.concat(chunks); console.log('Data: ', data); }) }).listen(8080) 

这里使用Buffer.concat ,它简单地连接所有的缓冲区并返回一个大的缓冲区。 您也可以使用相同的concat-stream模块 :

 const http = require('http'); const concat = require('concat-stream'); http.createServer((request, response) => { concat(request, data => { console.log('Data: ', data); }); }).listen(8080) 

如果您尝试接受HTML表单提交时没有文件,或者使用默认内容types来处理jQuery ajax调用,那么内容types是application/x-www-form-urlencodeduft-8编码。 您可以使用querystring模块对其进行反序列化并访问属性:

 const http = require('http'); const concat = require('concat-stream'); const qs = require('querystring'); http.createServer((request, response) => { concat(request, buffer => { const data = qs.parse(buffer.toString()); console.log('Data: ', data); }); }).listen(8080) 

如果您的内容types是JSON,您可以简单地使用JSON.parse而不是qs.parse 。

如果你正在处理文件或处理多部分内容types,那么在这种情况下,你应该使用像强大的东西,从而消除处理它的所有痛苦。 看看我的其他答案 ,我发布了有用的链接和多部分内容的模块。

如果你不想parsing内容,而是把它传递到别的地方,例如把它作为数据发送给另一个http请求,或者把它保存到一个文件中,我build议用pipe道来缓冲它,因为它会less一些代码,处理反压力更好,它会占用更less的内存,在某些情况下更快。

所以如果你想把内容保存到一个文件中:

  http.createServer((request, response) => { request.pipe(fs.createWriteStream('./request')); }).listen(8080) 

正如其他答案一样,记住恶意客户端可能会向您发送大量数据以使您的应用程序崩溃或填充您的内存,从而保护您的内容,确保您放弃发送数据的请求通过一定的限制。 如果您不使用库来处理传入的数据。 我会build议使用像stream量计 ,如果达到指定的限制可以中止请求的东西:

 limitedStream = request.pipe(meter(1e7)); limitedStream.on('data', ...); limitedStream.on('end', ...); 

要么

 request.pipe(meter(1e7)).pipe(createWriteStream(...)); 

要么

 concat(request.pipe(meter(1e7)), ...); 

也尝试使用npm模块,而不是自己实现,因为他们可能会更好地处理边缘案例。 为了expression,我build议使用body-parser 。 对于koa,还有一个类似的模块 。

如果你不使用框架, 身体是相当好的。

对于任何人想知道如何在没有安装Web框架的情况下做这个简单的任务,我设法把它们放在一起。 几乎没有生产准备,但似乎工作。

 function handler(req, res) { var POST = {}; if (req.method == 'POST') { req.on('data', function(data) { data = data.toString(); data = data.split('&'); for (var i = 0; i < data.length; i++) { var _data = data[i].split("="); POST[_data[0]] = _data[1]; } console.log(POST); }) } } 

您可以使用body-parser ,Node.js正文parsing中间件。

首先加载body-parser

 $ npm install body-parser --save 

一些示例代码

 var express = require('express') var bodyParser = require('body-parser') var app = express() app.use(bodyParser.urlencoded({ extended: false })) app.use(bodyParser.json()) app.use(function (req, res) { var post_data = req.body; console.log(post_data); }) 

更多文档可以在这里find

如果您不想将数据与datacallback一起分块,则可以使用如下所示的readablecallback:

 // Read Body when Available request.on("readable", function(){ request.body = ''; while (null !== (request.body += request.read())){} }); // Do something with it request.on("end", function(){ request.body //-> POST Parameters as String }); 

这种方法修改了传入的请求,但只要你完成你的回应,请求将被垃圾收集,所以这不应该是一个问题。

先进的方法是首先检查身体的大小,如果你害怕巨大的身体。

下面是如何使用node-strongidable的方法 :

 var formidable = require("formidable"); var form = new formidable.IncomingForm(); form.parse(request, function (err, fields) { console.log(fields.parameter1); console.log(fields.parameter2); // ... }); 

您需要使用request.on('data', function(chunk) {...})以块的forms接收POST数据

 const http = require('http'); http.createServer((req, res) => { if (req.method == 'POST') { whole = '' req.on('data', (chunk) => { # consider adding size limit here whole += chunk.toString() }) req.on('end', () => { console.log(whole) res.writeHead(200, 'OK', {'Content-Type': 'text/html'}) res.end('Data received.') }) } }).listen(8080) 

您应该考虑在指定的位置添加一个尺寸限制,如jh所示 。

有多种方法可以做到这一点。 但是,我知道的最快捷的方法是将Express.js库与body-parser一起使用。

 var express = require("express"); var bodyParser = require("body-parser"); var app = express(); app.use(bodyParser.urlencoded({extended : true})); app.post("/pathpostdataissentto", function(request, response) { console.log(request.body); //Or console.log(request.body.fieldName); }); app.listen(8080); 

这可以用于string,但是如果POST数据包含JSON数组,则会将bodyParser.urlencoded更改为bodyParser.json。

更多信息: http : //www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/

如果你不想使用像Express这样的整个框架,但是你也需要不同的forms,包括上传,那么福尔马林可能是一个不错的select。

它在Node.js模块中列出

如果您使用的是Express.js ,那么在您访问req.body之前,您必须添加中间件bodyParser:

 app.use(express.bodyParser()); 

然后你可以问

 req.body.user 
  1. 从npm安装“body-parser”。
  2. 然后打开app.ts – > write – > var bodyParser = require('body-parser');
  3. 那么你需要在app.ts模块中写入app.use(bodyParser.json())
  4. 请记住,在顶部或在任何模块声明前包含app.use(bodyParser.json())app.use(bodyParser.json())app.use('/ user',user);
  5. 然后使用var postdata = req.body;

谢谢

限制POST大小避免泛滥您的节点应用程序。 有一个伟大的原体模块,适合快递和连接,可以帮助您限制请求的大小和长度。

我find了一个video,介绍如何实现这一点: https : //www.youtube.com/watch?v=nuw48-u3Yrg

它使用默认的“http”模块以及“querystring”和“stringbuilder”模块。 应用程序从网页中获取两个数字(使用两个文本框),并在提交后返回这两个数字(以及在文本框中保留值)。 这是我能在其他地方find的最好的例子。

相关源码:

 var http = require("http"); var qs = require("querystring"); var StringBuilder = require("stringbuilder"); var port = 9000; function getCalcHtml(req, resp, data) { var sb = new StringBuilder({ newline: "\r\n" }); sb.appendLine("<html>"); sb.appendLine(" <body>"); sb.appendLine(" <form method='post'>"); sb.appendLine(" <table>"); sb.appendLine(" <tr>"); sb.appendLine(" <td>Enter First No: </td>"); if (data && data.txtFirstNo) { sb.appendLine(" <td><input type='text' id='txtFirstNo' name='txtFirstNo' value='{0}'/></td>", data.txtFirstNo); } else { sb.appendLine(" <td><input type='text' id='txtFirstNo' name='txtFirstNo' /></td>"); } sb.appendLine(" </tr>"); sb.appendLine(" <tr>"); sb.appendLine(" <td>Enter Second No: </td>"); if (data && data.txtSecondNo) { sb.appendLine(" <td><input type='text' id='txtSecondNo' name='txtSecondNo' value='{0}'/></td>", data.txtSecondNo); } else { sb.appendLine(" <td><input type='text' id='txtSecondNo' name='txtSecondNo' /></td>"); } sb.appendLine(" </tr>"); sb.appendLine(" <tr>"); sb.appendLine(" <td><input type='submit' value='Calculate' /></td>"); sb.appendLine(" </tr>"); if (data && data.txtFirstNo && data.txtSecondNo) { var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo); sb.appendLine(" <tr>"); sb.appendLine(" <td>Sum: {0}</td>", sum); sb.appendLine(" </tr>"); } sb.appendLine(" </table>"); sb.appendLine(" </form>") sb.appendLine(" </body>"); sb.appendLine("</html>"); sb.build(function (err, result) { resp.write(result); resp.end(); }); } function getCalcForm(req, resp, data) { resp.writeHead(200, { "Content-Type": "text/html" }); getCalcHtml(req, resp, data); } function getHome(req, resp) { resp.writeHead(200, { "Content-Type": "text/html" }); resp.write("<html><html><head><title>Home</title></head><body>Want to some calculation? Click <a href='/calc'>here</a></body></html>"); resp.end(); } function get404(req, resp) { resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" }); resp.write("<html><html><head><title>404</title></head><body>404: Resource not found. Go to <a href='/'>Home</a></body></html>"); resp.end(); } function get405(req, resp) { resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" }); resp.write("<html><html><head><title>405</title></head><body>405: Method not supported</body></html>"); resp.end(); } http.createServer(function (req, resp) { switch (req.method) { case "GET": if (req.url === "/") { getHome(req, resp); } else if (req.url === "/calc") { getCalcForm(req, resp); } else { get404(req, resp); } break; case "POST": if (req.url === "/calc") { var reqBody = ''; req.on('data', function (data) { reqBody += data; if (reqBody.length > 1e7) { //10MB resp.writeHead(413, 'Request Entity Too Large', { 'Content-Type': 'text/html' }); resp.end('<!doctype html><html><head><title>413</title></head><body>413: Request Entity Too Large</body></html>'); } }); req.on('end', function () { var formData = qs.parse(reqBody); getCalcForm(req, resp, formData); }); } else { get404(req, resp); } break; default: get405(req, resp); break; } }).listen(port); 

如果涉及file upload,浏览器通常将其作为"multipart/form-data"内容types发送。 你可以在这种情况下使用它

 var multipart = require('multipart'); multipart.parse(req) 

参考文献1

参考2

在这样的表单字段上

  <input type="text" name="user[name]" value="MyName"> <input type="text" name="user[email]" value="myemail@somewherefarfar.com"> 

上面的一些答案会失败,因为他们只支持平面数据。

现在我正在使用Casey Chu的答案,但是用“qs”代替“querystring”模块。 这是“body-parser”使用的模块。 所以,如果你想要嵌套的数据,你必须安装qs。

 npm install qs --save 

然后replace第一行,如:

 //var qs = require('querystring'); var qs = require('qs'); function (request, response) { if (request.method == 'POST') { var body = ''; request.on('data', function (data) { body += data; // Too much POST data, kill the connection! // 1e6 === 1 * Math.pow(10, 6) === 1 * 1000000 ~~~ 1MB if (body.length > 1e6) request.connection.destroy(); }); request.on('end', function () { var post = qs.parse(body); console.log(post.user.name); // should work // use post['blah'], etc. }); } } 

对于那些使用原始的二进制POST上传而没有编码开销,你可以使用

客户:

 var xhr = new XMLHttpRequest(); xhr.open("POST", "/api/upload", true); var blob = new Uint8Array([65,72,79,74]); // or eg recorder.getBlob() xhr.send(blob); 

服务器:

 var express = require('express'); var router = express.Router(); var fs = require('fs'); router.use (function(req, res, next) { var data=''; req.setEncoding('binary'); req.on('data', function(chunk) { data += chunk; }); req.on('end', function() { req.body = data; next(); }); }); router.post('/api/upload', function(req, res, next) { fs.writeFile("binaryFile.png", req.body, 'binary', function(err) { res.send("Binary POST successful!"); }); }); 

这应该工作:

 app.use(bodyParser.json()); app.post("/want_pay", function(req, res){ var val=req.body.your_value; console.log(val); }); 

你可以提取邮政参数,而不使用快递。

1: nmp install multiparty

2:import多方。 as var multiparty = require('multiparty');

3:`

 if(req.method ==='POST'){ var form = new multiparty.Form(); form.parse(req, function(err, fields, files) { console.log(fields['userfile1'][0]); }); } 

4:和HTML格式是。

 <form method=POST enctype=multipart/form-data> <input type=text name=userfile1><br> <input type=submit> </form> 

我希望这会对你有用。 谢谢。