Как обрабатывать POST-данные в Node.js?

638

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

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

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

Есть библиотека или взломать?

Мин-Tang
источник

Ответы:

553

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

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)
});
Baggz
источник
45
Функциональность на самом деле в модуле BodyParser в соединении, если вы хотите использовать точку входа более низкого уровня.
Джулиан Берч
14
Я смущен. Как name = "user [email]" соответствует request.body.email?
sbose
36
Бог!! Я схожу с ума от необходимости читать 3 doumentations одновременно для одного и того же фреймворка: / nodejs.org/api/http.html , senchalabs.org/connect & expressjs.com/guide.html
Салман фон Аббас
15
Это не сработало для меня, пока я не добавил app.use(express.bodyParser());.
Петтис
13
Express - это узел jQuery для JS на стороне клиента. Каждый раз, когда я обращаюсь к справке по google для узла, я получаю эти "хромые выражения"! ответы. Неужели так сложно разобрать данные поста, что это оправдывает установку целого веб-фреймворка?
Шон Уиннери
710

Вы можете использовать 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);
Кейси Чу
источник
8
@ thejh Хм, это хорошая мысль. Не должно быть сложным добавить это, поэтому я оставлю это вне примера, чтобы все было просто.
Кейси Чу
72
Разработка веб-сервера node.js изобилует middlewarez, который требует от вас изучения их часами, чтобы сэкономить ваши минуты на кодирование. Не говоря уже о скудной документации, которую предлагают почти все. И ваша заявка в конечном итоге полагается на критерии других людей, а не на ваши. Плюс любое количество проблем с производительностью.
Хуан Ланус
4
var POST = qs.parse(body); // use POST только для таких нубов, как я: если имя поля ввода текста «пользователь», Post.userбудут отображаться данные этого поля. Напримерconsole.log(Post.user);
Майкл Мёллер
5
Вы также можете использовать readableобратный вызов вместо встраивания данных в строку тела. После того, как его уволят, тело доступно черезrequest.read();
Томас Фанкхаузер
4
Обратите внимание, что req.connection.destroy(); это не мешает выполнению обратных вызовов! Например, обратный вызов "on end" будет выполнен с усеченным телом! Это, вероятно, не то, что вы хотите ...
Collimarco
149

Обязательно разорвите соединение, если кто-то попытается заполнить вашу 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

        });
    }
}
thejh
источник
53
Вы также можете вернуть HTTP 413 Error Code (Request Entity Too Large)
neoascetic
1
@SSHThis: Нет, это 1 * 10 ^ 6 = 1000000.
thejh
@tq: в этом случае POST [имя] (например, POST ["foo"]).
thejh
2
var POST = qs.parse(body); // use POST только для нубов: когда имя поля ввода текста «пользователь», Post.user покажет данные этого поля. например console.log (Post.user);
Майкл Мёллер
2
Может ли кто-нибудь помочь, если я напишу {'Name': 'Joe'}, я получу {{'Name': 'Joe'}: ''} после qs.Parse (POST) ...
Matt Canty
118

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

основы

Когда вызывается обратный вызов 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)

Разбор контента

Если вы пытаетесь принять отправку 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-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 . Для Коа есть аналогичный модуль .

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

Фарид Нури Нешат
источник
Спасибо, я использовал ваш код и получил загадочные дублированные сообщения. Может быть, переменная requestиспользуется повторно и request.on('end')вызывается несколько раз? Как я могу избежать этого?
Ян Кинг Инь
Я не могу сказать почему, не увидев ваш код Обратите внимание, что для каждого запроса request.on('end', ...)будет вызываться.
Фарид Нури Нешат
Возможно, это не связано с вашим кодом, я делаю отправленные сервером события и, возможно, облажался ... ваш код работает нормально, в любом случае, спасибо :)
Ян Кинг Инь
Как это влияет на производительность по сравнению с обработкой запроса GET без обработчика 'end', т.е. без буферизации фрагментов?
JSON
1
Это здесь лучший ответ на вопрос. 🧐
montrealist
103

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

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);
Mahn
источник
Не следует ли перенести эту проверку в отдельное промежуточное ПО, чтобы она могла проверять слишком большие запросы на все запросы post / put
Павел Николов
@PavelNikolov это предназначено главным образом для быстрых и грязных заданий, в противном случае, вероятно, лучше использовать Express, как рекомендует принятый здесь ответ (который, вероятно, также заботится об управлении большими запросами). Не стесняйтесь модифицировать и «раскошелиться» на ваш вкус.
Ман
Как насчет метода .read ()? Это не поддерживается модулем http? Например. response.read ()
BT
Эй, просто любопытно - почему вы поместили полезную нагрузку в объект ответа (response.post), а не в объект запроса?
Джотэм
@ Джотэм, хороший вопрос ... Я понятия не имею, почему я не заметил этого раньше, но нет причины, почему это должно быть, response.postа не более логичным request.post. Я обновил пост.
Ман
83

Будет лучше, если вы закодируете свои данные в 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));
        });
    }
}
Льюис
источник
1
Это то, что сработало для меня. Оказывается, другие решения возвращали строку, которая выглядела как JSON, но не была проанализирована. Вместо того qs.parse(), чтобы JSON.parse()превратить тело в нечто полезное. Пример:, var post = JSON.parse(body);затем получите доступ к данным с помощью post.fieldname. (Мораль истории, если вы не понимаете, что видите, не забывайте typeof!)
wmassingham
12
Просто знайте, что вы должны попытаться поймать функцию JSON.parse, потому что, если я хочу завершить работу вашего приложения, просто отправьте тело с необработанным текстом.
Ecarrizo
Вы должны использовать, request.setEncodingчтобы заставить это работать должным образом, иначе это может не обрабатывать символы не ascii должным образом.
Фарид Нури Нешат
37

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

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);
        })
    }
}
Шон Уиннери
источник
Наконец, ПОЛНОСТЬЮ РАБОТАЮЩЕЕ решение этой странной проблемы ... предыдущий ответ также очень помог понять, почему в запросе не было никаких данных при запуске обратного вызова. Большое спасибо!
Луис-бр
3
1) Этот ответ предполагает, что данные являются строкой. Плохое предположение, в общем случае. 2) Этот ответ предполагает, что данные поступают в один блок. В противном случае разбиение на '=' даст непредсказуемый результат. Плохое предположение, в общем случае.
Константин
@Konstantin На самом деле этот ответ предполагает, что данные являются буфером. Проверь это. stackoverflow.com/questions/14551194/… Также это. millermedeiros.github.io/mdoc/examples/node_api/doc/…
Шон
16

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

Больше документации можно найти здесь

исходный код
источник
9

Вот как вы можете это сделать, если вы используете 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);
    // ...
});
Дмитрий Ефименко
источник
У меня возникла проблема с путем, когда я пытаюсь использовать путь или путь + имя для доступа к файлу с помощью lwip.open (путь или путь + имя. Я получаю сообщение об ошибке как нераспознанное изображение.
Lion789
7

Если вы предпочитаете использовать чистый 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}`);
});

Алексей Трехлеб
источник
6

1) Установить '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;
Эр Шубхам Патидар
источник
5

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

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

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

Томас Фанкхаузер
источник
Удобный способ сделать это, но как вы «сначала проверяете размер тела» таким образом, который не может быть обманут злонамеренным запросом?
doug65536
requestявляется нормальным потоком node.js, поэтому вы можете проверить request.headersдлину тела и при необходимости прервать запрос.
Томас Фанкхаузер
1
@ThomasFankhauser Длина тела в заголовке может быть неправильным значением или даже не указана. Правильный способ сделать это, когда тело прибывает и вы буферизируете его, вы проверяете размер, чтобы убедиться, что оно не превышает предела.
Фарид Нури Нешат
4

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

nikodean2
источник
4

Вам нужно получать 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)

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

Zaz
источник
Является ли это более подверженным приступу медленного лори?
Nodejs менее чувствителен к slow-loris, чем, например, php - потому что он не создает большой объект сеанса вокруг каждого http-соединения. Тем не менее, похоже, что этот код все еще может вводить уязвимость медленного Лориса. Это может быть предотвращено с помощью a, setTimeoutкоторый завершает соединение через определенный период времени, если полный запрос не получен в этом окне.
Гершом
4

Экспресс v4.17.0

app.use(express.urlencoded( {extended: true} ))
antelove
источник
3

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

app.use(express.bodyParser());

Тогда вы можете попросить

req.body.user
Patricios
источник
Большая часть промежуточного программного обеспечения (например, bodyParser) больше не поставляется вместе с Express и должна устанавливаться отдельно. Посмотрите ответ от @ nikodean2 выше для более текущего ответа
Джефф Коллиер
app.use (bodyParser ()); работает, но выдает мне устаревшие сообщения об ошибках
Крис Аллинсон
2

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

Это перечислено в модулях Node.js

Павел Корягин
источник
1

Я нашел видео, которое объясняет, как этого добиться: 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) { //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);
user203687
источник
1

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

Вы можете использовать промежуточное программное обеспечение Express , в которое теперь встроен анализатор тела. Это означает, что все, что вам нужно сделать, это следующее:

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 post
  res.sendStatus(200)
})

Этот пример кода ES6 с Express 4.16.x

Большие деньги
источник
0

Вы можете извлечь параметр сообщения без использования экспресс.

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 method=POST enctype=multipart/form-data>
<input type=text name=userfile1><br>
<input type=submit>
</form>

Я надеюсь, что это будет работать для вас. Спасибо.

Маниш Сингх
источник
0

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

EricSonaron
источник
0

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

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

Ссылка 1

Ссылка 2

user3526
источник
0

На полях формы, как эти

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

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

Сейчас я использую ответ Кейси Чу, но с модулем «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.
        });
    }
}
Геза Тури
источник
0

Вы можете легко отправить и получить ответ на запрос POST, используя «Запрос - упрощенный HTTP-клиент» и Javascript Promise.

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);
            }
        });
    });
}
Kaveesha Baddage
источник
0

Вам нужно использовать bodyParser (), если вы хотите, чтобы данные формы были доступны в req.body. body-parser анализирует ваш запрос и преобразует его в формат, из которого вы можете легко извлечь необходимую информацию.

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

Извлечение имени пользователя и пароля из вашего запроса выполняется так же просто, как показано ниже, если вы используете body-parser.

.............................................................

var loginDetails = {

username : request.body.username,

password : request.body.password

};
Рубин Бхандари
источник
0

ОДИН ЛАЙНЕР без СРЕДНЕГО ОБЕСПЕЧЕНИЯ
Если вы публикуете следующие данные, то
'name':'ABC'
вы можете проанализировать их, используя следующий один лайнер,

require('url').parse(req.url, true).query.name
Хардик Триведи
источник