Как вы извлекаете данные POST в Node.js?

Как вы извлекаете данные формы ( form[method="post"] ) и загружаете файлы, отправленные из метода HTTP POST в Node.js ?

Я читал документацию, искал и ничего не нашел.

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

Есть ли библиотека или хак?

Если вы используете Express (высокопроизводительная высокоуровневая веб-разработка для Node.js), вы можете сделать это:

HTML:

 

JavaScript:

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

ОБНОВЛЕНО 1 июня / 2016:

Приведенный выше метод устаревает:

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

Вы можете использовать модуль 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. }); } } 

Например, если у вас есть поле input с age имен, вы можете получить к нему доступ, используя post переменной:

 console.log(post.age); 

Не забудьте убить соединение, если кто-то пытается затопить вашу оперативную память!

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

Вот очень простая shell без frameworks, основанная на других ответах и ​​статьях, опубликованных здесь:

 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, это когда сервер фактически получил все заголовки для запроса, но возможно, что данные еще не получены, поэтому мы должны ждать его. Объект запроса http (экземпляр http.IncomingMessage) на самом деле является читаемым streamом . В читаемых streamах всякий раз, когда приходит кусок данных, происходит событие 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, который заставляет stream испускать строки, интерпретированные с данной кодировкой, и обрабатывает многобайтовые символы должным образом.

Теперь вы, вероятно, не заинтересованы в каждом куске по своему усмотрению, поэтому в этом случае, возможно, вы хотите его буферизировать следующим образом:

 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) 

Если вы пытаетесь принять POST-представление HTML-форм без файлов или передавая jQuery ajax- вызовы с типом контента по умолчанию, тогда тип контента будет application/x-www-form-urlencoded с кодировкой uft-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) 

Если ваш тип контента – это JSON, вы можете просто использовать JSON.parse вместо qs.parse .

Если вы имеете дело с файлами или обрабатываете тип многостраничного контента, тогда в этом случае вы должны использовать что-то вроде грозного, которое устраняет всю боль от работы с ним. Взгляните на этот другой ответ, где я разместил полезные ссылки и модули для многостраничного контента.

Если вы не хотите анализировать контент, а скорее передаете его в другое место, например, отправляете его другому HTTP-запросу в качестве данных или сохраняете его в файле, я предлагаю его проложить, а не буферизировать его, поскольку он будет меньше кода, лучше справится с обратным давлением, это займет меньше памяти и в некоторых случаях быстрее.

Поэтому, если вы хотите сохранить содержимое в файл:

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

Как отмечают другие ответы, я помню, что вредоносные клиенты могут отправить вам огромное количество данных, чтобы свернуть приложение или заполнить вашу память, чтобы защитить их, чтобы вы отбрасывали запросы, которые выдают данные за определенный предел. Если вы не используете библиотеку для обработки входящих данных. Я бы предложил использовать что-то вроде streamа-метра, который может прервать запрос, если достигнет указанного предела:

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

или

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

или

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

Также попробуйте использовать модули npm, а не реализовать самостоятельно, поскольку они, вероятно, лучше справятся с краевыми случаями. Для выражения я предлагаю использовать body-parser . Для koa есть аналогичный модуль .

Если вы не используете фреймворк, тело неплохое.

Для тех, кто задается вопросом, как сделать эту тривиальную задачу без установки веб-фреймворка, мне удалось совместить это вместе. Вряд ли производство готово, но, похоже, оно работает.

 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.

Первый 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); }) 

Дополнительную документацию можно найти здесь

Ссылка: https://nodejs.org/ru/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 }); 

Вот как вы можете это сделать, если используете node-magnidable :

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

Если вы не хотите разбивать свои данные вместе с обратным вызовом 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 }); 

Этот подход изменяет входящий запрос, но как только вы закончите свой ответ, запрос будет собран с мусором, так что это не должно быть проблемой.

Перспективным подходом было бы сначала проверить размер тела, если вы боитесь огромных тел.

Существует несколько способов сделать это. Однако самый быстрый способ, который я знаю, – использовать библиотеку 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); 

Это может работать для строк, но я бы изменил bodyParser.urlencoded на bodyParser.json, а если данные POST содержат массив JSON.

Дополнительная информация: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/

Вы должны получить данные POST в кусках с помощью request.on('data', function(chunk) {...})

 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) 

Вы должны рассмотреть возможность добавления ограничения размера в указанной позиции, как предполагалось .

Если вы используете Express.js , прежде чем вы сможете получить доступ к req.body, вы должны добавить middleware bodyParser:

 app.use(express.bodyParser()); 

Затем вы можете попросить

 req.body.user 

И если вы не хотите использовать всю инфраструктуру, например Express, но вам также нужны различные формы, включая закачки, то формалин может быть хорошим выбором.

Он указан в модулях Node.js

  1. Установите 'body-parser' из npm.
  2. затем откройте app.ts -> write -> 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;

Для тех, кто использует загруженную двоичную загрузку 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!"); }); }); 

Ограничьте размер POST, чтобы не нападать на приложение вашего узла. Существует отличный модуль сырого тела , подходящий как для express-связи, так и для подключения, который может помочь вам ограничить запрос по размеру и длине.

Я нашел видео, в котором объясняется, как этого добиться: https://www.youtube.com/watch?v=nuw48-u3Yrg

Он использует модуль по умолчанию «http» вместе с модулями «querystring» и «stringbuilder». Приложение принимает два номера (используя два текстовых поля) с веб-страницы и после отправки возвращает сумму этих двух (наряду с сохранением значений в текстовых windowsх). Это лучший пример, который я могу найти где-нибудь еще.

Связанный исходный код:

 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(""); sb.appendLine(" "); sb.appendLine(" 
"); sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); if (data && data.txtFirstNo) { sb.appendLine(" ", data.txtFirstNo); } else { sb.appendLine(" "); } sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); if (data && data.txtSecondNo) { sb.appendLine(" ", data.txtSecondNo); } else { sb.appendLine(" "); } sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); sb.appendLine(" "); if (data && data.txtFirstNo && data.txtSecondNo) { var sum = parseInt(data.txtFirstNo) + parseInt(data.txtSecondNo); sb.appendLine(" "); sb.appendLine(" ", sum); sb.appendLine(" "); } sb.appendLine("
Enter First No:
Enter Second No:
Sum: {0}
"); sb.appendLine("
") sb.appendLine(" "); sb.appendLine(""); 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("HomeWant to some calculation? Click here"); resp.end(); } function get404(req, resp) { resp.writeHead(404, "Resource Not Found", { "Content-Type": "text/html" }); resp.write("404404: Resource not found. Go to Home"); resp.end(); } function get405(req, resp) { resp.writeHead(405, "Method not supported", { "Content-Type": "text/html" }); resp.write("405405: Method not supported"); resp.end(); } http.createServer(function (req, resp) { switch (req.method) { case "GET": if (req.url === "/") { getHome(req, resp); } else if (req.url === "https://stackoverflow.com/calc") { getCalcForm(req, resp); } else { get404(req, resp); } break; case "POST": if (req.url === "https://stackoverflow.com/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('413413: Request Entity Too Large'); } }); 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);

Если это связано с загрузкой файла, браузер обычно отправляет его как тип контента "multipart/form-data" . Вы можете использовать это в таких случаях

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

Ссылка 1

Ссылка 2

В полях формы, подобных этим

    

некоторые из приведенных выше ответов не будут выполнены, поскольку они поддерживают только плоские данные.

На данный момент я использую ответ Кейси Чу, но с «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 ~~~ 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 без использования выражения.

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.

 

Надеюсь, это сработает для вас. Благодарю.

  • Синхронные запросы к базе данных с помощью Node.js
  • Ошибка ввода машинописного текста TS2304: невозможно найти имя 'require'
  • Заseleniumие Mongoose vs вложенность объекта
  • Строка Node.js Mongoose.js для функции ObjectId
  • Как получить доступ к параметрам GET после «?» В Express?
  • Как установить модуль глобально с помощью npm?
  • выборочная проверка mongoose с использованием 2 полей
  • Определить корень проекта из запущенного приложения node.js
  • паспорт req.isAuthenticated всегда возвращает false, даже когда я делаю hardcode (null, true)
  • Узел js ECONNRESET
  • Лучший подход к streamу HTTP в реальном времени для видеоконтента HTML5
  • Давайте будем гением компьютера.