Многие ответы здесь уже не являются хорошими практиками или ничего не объясняют, поэтому я и пишу это.
Когда вызывается функция обратного вызова 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
. Вы можете использовать модуль строки запроса , чтобы десериализовать его и получить доступ к свойствам:
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, реализовав их самостоятельно, поскольку они, вероятно, будут лучше обрабатывать крайние случаи. Для экспресса я предлагаю использовать body-parser . Для koa существует аналогичный модуль .
Если вы не используете фреймворк, body довольно хорошо.