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

我已经阅读了文档,谷歌搜索并没有发现任何东西。

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

有图书馆还是黑客?


#1楼

这是一个非常简单的无框架包装器,它基于此处发布的其他答案和文章:

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 hereresponse.writeHead(200, "OK", {'Content-Type': 'text/plain'});response.end();});} else {response.writeHead(200, "OK", {'Content-Type': 'text/plain'});response.end();}}).listen(8000);

#2楼

如果您不想将数据与data回调一起分块,则始终可以使用如下所示的readable回调:

// 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
});

这种方法修改了传入的请求,但是一旦您完成响应,该请求就会被垃圾回收,因此这不会成为问题。

如果您担心庞大的身体,一种高级方法是首先检查身体大小。


#3楼

如果使用Express.js ,则必须先添加中间件bodyParser,然后才能访问req.body:

app.use(express.bodyParser());

那你可以要求

req.body.user

#4楼

如果您使用node-formidable,可以按照以下方法进行操作:

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

#5楼

如果将数据编码为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));});}
}

#6楼

您可以使用body-parser ,即Node.js主体解析中间件。

首次加载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);
})

更多文档可以在这里找到


#7楼

对于想知道如何在不安装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);})}
}

#8楼

您可以不使用express提取post参数。

1: nmp install multiparty

2:导入多方。 如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 IS。

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

希望这对您有用。 谢谢。


#9楼

限制POST大小,避免淹没您的节点应用程序。 有一个很棒的原始模块,适用于快速连接和连接,可以帮助您通过大小和长度来限制请求。


#10楼

我找到了一段视频,解释了如何实现此目的: https : //www.youtube.com/watch?v=nuw48-u3Yrg

它使用默认的“ http”模块以及“ querystring”和“ stringbuilder”模块。 该应用程序从网页上获取两个数字(使用两个文本框),并在提交后返回这两个数的总和(以及将值持久保存在文本框中)。 这是我在其他任何地方都能找到的最佳示例。

相关源代码:

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) { //10MBresp.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);

#11楼

如果涉及文件上传,则浏览器通常将其作为"multipart/form-data"内容类型发送。 您可以在这种情况下使用

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

参考1

参考2


#12楼

有多种方法可以做到这一点。 但是,我知道最快的方法是将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);//Orconsole.log(request.body.fieldName);
});app.listen(8080);

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

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


#13楼

在这样的表单字段上

   <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

然后像这样替换第一行:

//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 ~~~ 1MBif (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.});}
}

#14楼

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

客户:

var xhr = new XMLHttpRequest();
xhr.open("POST", "/api/upload", true);
var blob = new Uint8Array([65,72,79,74]); // or e.g. 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!");});
});

#15楼

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

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

您应该考虑按照建议的在指定位置添加大小限制。


#16楼

这里有很多答案已经不是很好的做法,或者什么也没解释,所以这就是我写这篇文章的原因。

基本

调用http.createServer的回调时,是服务器实际上已接收到该请求的所有标头,但是可能尚未收到数据,因此我们必须等待。 http请求对象(一个http.IncomingMessage实例)实际上是一个可读 流 。 在可读流中,每当有数据块到达时, 都会发出一个data 事件 (假设您已经注册了一个回调),并且在所有数据块到达时都会发出一个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)

将缓冲区转换为字符串

如果尝试这样做,您会注意到这些块是缓冲区 。 如果您不处理二进制数据,而需要使用字符串,则建议使用request.setEncoding方法,该方法将使流发出以给定编码解释的字符串,并正确处理多字节字符。

缓冲块

现在您可能对每个块都不感兴趣,因此在这种情况下,您可能想要像这样缓冲它:

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表单POST提交或使用默认的内容类型处理jQuery ajax调用,则该内容类型是使用uft-8编码的application/x-www-form-urlencoded 。 您可以使用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)

如果您的内容类型是JSON,则只需使用JSON.parse而不是qs.parse即可 。

如果您要处理文件或处理多部分内容类型,则在这种情况下,应使用“可怕”之类的东西来消除处理它的所有麻烦。 看看我的其他答案 ,我在其中发布了有用的链接和有关多部分内容的模块。

管道

如果您不想解析内容而是将其传递到其他地方,例如将其作为数据发送到另一个http请求或将其保存到文件中,我建议您对其进行管道化而不是对其进行缓冲,因为它会少一些代码,更好地处理背压,它将占用更少的内存,并且在某些情况下会更快。

因此,如果要将内容保存到文件中:

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

限制数据量

正如其他答案所指出的那样,请记住,恶意客户端可能会向您发送大量数据,从而使您的应用程序崩溃或填充您的内存,以保护您确保丢弃发出数据的请求超过一定限制。 如果您不使用库来处理传入的数据。 我建议使用类似stream-meter的方法 ,如果达到指定的限制,该方法可以中止请求:

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

要么

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

要么

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

NPM模块

虽然我在上面描述了如何使用HTTP请求正文来简单地缓冲和解析内容,但我建议使用这些模块之一而不是自己实现,因为它们可能会更好地处理边缘情况。 为了表达意见,我建议使用body-parser 。 对于koa,有一个类似的模块 。

如果您不使用框架,那么身体会很好。


#17楼

如果使用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>

API客户端:

fetch('/', {method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify({user: {name: "John",email: "john@example.com"}})
});

Node.js :(自Express v4.16.0起)

// Parse URL-encoded bodies (as sent by HTML forms)
app.use(express.urlencoded());// Parse JSON bodies (as sent by API clients)
app.use(express.json());// Access the parse results as request.body
app.post('/', function(request, response){console.log(request.body.user.name);console.log(request.body.user.email);
});

Node.js :(适用于Express <4.16.0)

const bodyParser = require("body-parser");/** 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)
});

#18楼

您可以使用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 ~~~ 1MBif (body.length > 1e6)request.connection.destroy();});request.on('end', function () {var post = qs.parse(body);// use post['blah'], etc.});}
}

现在,例如,如果您有一个名为ageinput字段,则可以使用变量post访问:

console.log(post.age);

#19楼

1)从npm安装'body-parser'

2)然后在您的app.ts中

var bodyParser = require('body-parser');

3)那你需要写

app.use(bodyParser.json())

app.ts模块中

4)请记住,您包括

app.use(bodyParser.json())

在顶部或任何模块声明之前。

例如:

app.use(bodyParser.json())
app.use('/user',user);

5)然后使用

var postdata = req.body;

#20楼

参考: https : //nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/

let body = [];
request.on('data', (chunk) => {body.push(chunk);
}).on('end', () => {body = Buffer.concat(body).toString();// at this point, `body` has the entire request body stored in it as a string
});

#21楼

如果您更喜欢使用纯Node.js,则可以提取POST数据,如下所示:

 // Dependencies const StringDecoder = require('string_decoder').StringDecoder; const http = require('http'); // Instantiate the HTTP server. const httpServer = http.createServer((request, response) => { // Get the payload, if any. const decoder = new StringDecoder('utf-8'); let payload = ''; request.on('data', (data) => { payload += decoder.write(data); }); request.on('end', () => { payload += decoder.end(); // Parse payload to object. payload = JSON.parse(payload); // Do smoething with the payload.... }); }; // Start the HTTP server. const port = 3000; httpServer.listen(port, () => { console.log(`The server is listening on port ${port}`); }); 

#22楼

您可以使用快速中间件,该中间件现在内置了主体解析器。 这意味着您需要做的是以下几点:

import express from 'express'const app = express()app.use(express.json())app.post('/thing', (req, res) => {console.log(req.body) // <-- this will access the body of the postres.sendStatus(200)
})

该代码示例是带有Express 4.16.x的ES6。


#23楼

您可以使用“请求-简化的HTTP客户端”和Javascript Promise轻松发送并获取POST请求的响应。

var request = require('request');function getData() {var options = {url: 'https://example.com',headers: {'Content-Type': 'application/json'}};return new Promise(function (resolve, reject) {var responseData;var req = request.post(options, (err, res, body) => {if (err) {console.log(err);reject(err);} else {console.log("Responce Data", JSON.parse(body));responseData = body;resolve(responseData);}});});
}

#24楼

如果希望表单数据在req.body中可用,则需要使用bodyParser()。 body-parser解析您的请求并将其转换为一种格式,您可以从中轻松提取您可能需要的相关信息。

例如,假设您在前端有一个注册表单。 您正在填充它,并请求服务器将详细信息保存在某处。

如果使用body-parser,从请求中提取用户名和密码将变得非常简单。

……………………………………………………。

var loginDetails = {username : request.body.username,password : request.body.password};

#25楼

快递v4.17.0

app.use(express.urlencoded( {extended: true} ))

#26楼

而且,如果您不想使用Express等整个框架,但还需要其他形式的表单,包括上载,那么福尔马林可能是一个不错的选择。

它在Node.js模块中列出


#27楼

如果有人试图淹没您的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 ~~~ 1MBif (body.length > 1e6) { // FLOOD ATTACK OR FAULTY CLIENT, NUKE REQUESTrequest.connection.destroy();}});request.on('end', function () {var POST = qs.parse(body);// use POST});}
}

如何在Node.js中处理POST数据?相关推荐

  1. 如何在node.js中发出HTTP POST请求?

    如何在node.js中使用数据发出出站HTTP POST请求? #1楼 如果您使用请求库,这会变得更容易. var request = require('request');request.post( ...

  2. 如何在Node.js中打印堆栈跟踪?

    本文翻译自:How to print a stack trace in Node.js? 有谁知道如何在Node.js中打印堆栈跟踪? #1楼 参考:https://stackoom.com/ques ...

  3. 如何在Node.js中获取本机本地IP地址

    最近在做Cloud related的项目时,遇到一个问题,就是如何在Node.js中获取本机的IP地址.Node.js提供的API中,只能获取本机的hostname. os = require('os ...

  4. 如何在Node.js中退出

    用于退出的命令是什么? (即终止Node.js进程) #1楼 从命令行, .exit就是你想要的: $ node > .exit $ 它在REPL文档中有记录 . REPL(Read-Eval- ...

  5. 如何在Node JS中卸载NPM模块?

    本文翻译自:How to uninstall npm modules in node js? As commonly known, any npm module can be installed by ...

  6. php能反序列化js的吗,javascript – 如何在node.js中反序列化PHP会话?

    我将 PHP $_SESSION数据存储在数据库中. 然后从Node.js服务器,我想获取该数据并反序列化它. con.query('SELECT user_id, data ' + 'FROM se ...

  7. mysql econnreset_如何在Node.js中调试错误ECONNRESET?

    我正在使用Socket.io运行Express.js应用程序用于聊天Web应用程序,并且在24小时内大约5次随机收到以下错误.节点进程将被永久封装,并立即重新启动. 问题是重新启动Express将我的 ...

  8. ENSP如何开启服务器的http_如何使用HTTP模块在Node.js中创建Web服务器(上)

    当你在浏览器中查看网页时,其实是在向互联网上的另一台计算机发出请求,然后它会将网页提供给你作为响应.你通过互联网与之交谈的那台计算机就是Web服务器,Web服务器从客户端(例如你的浏览器)接收HTTP ...

  9. 如何在Tensorflow.js中处理MNIST图像数据

    by Kevin Scott 凯文·斯科特(Kevin Scott) 如何在Tensorflow.js中处理MNIST图像数据 (How to deal with MNIST image data i ...

最新文章

  1. linux下mv命令移动目录的二种情况
  2. okhttp 工具类_HR常用的人才测评工具 ~ 团测系统
  3. 洛谷2505 [HAOI2012]道路(最短路计数)
  4. ABP vNext微服务架构详细教程——身份管理服务
  5. WAIC|高精准、低成本,九章云极DataCanvas突破AutoML难题
  6. ftp文件服务器杀毒,FTP远程查杀网页木马方法
  7. Windows核心编程_Miniblin(5) 前后端交互数据
  8. 内存测试软件 ddr 4,DDR4内存理论性能测试
  9. mybatis多参数传递(其中包括数组)
  10. python3 数据挖掘 之 爬取 智联招聘网站来巩固pandas
  11. MySQL表空间碎片
  12. DoIP节点连接状态管理
  13. 用c语言编写出的情话,c语言for情话
  14. Angular开发(三)-关于属性绑定与事件绑定
  15. 人工智能的马克思主义审视
  16. 高通WLAN框架学习(17)-- NIO和PNO
  17. 练习篇:完整实践——实现一个简易日记本应用
  18. 利用SPSS做数据分析②之数据处理2
  19. 源表搭建光电器件LIV特性测试实验平台
  20. C++:利用printf 输出string

热门文章

  1. 第一次装TFS的曲折经历
  2. Oracle 初始化参数文件pfile和spfile
  3. Hibernate的事务管理
  4. HSImageSidebarView
  5. 吴裕雄 Bootstrap 前端框架开发——Bootstrap 辅助类:在元素获取焦点时显示(如:键盘操作的用户)...
  6. IOS NSNotification 通知
  7. day12(html、css)
  8. 在 Ubuntu 中更换字体
  9. Ubuntu 16.04中vim编辑报错E138: Can‘t write viminfo file /root/.viminfo!
  10. 史上最硬核的rpm和dpkg依赖问题解决方案