Muitas respostas aqui não são mais boas práticas ou não explicam nada, por isso estou escrevendo isso.
Fundamentos
Quando o retorno de chamada de http.createServer é chamado, é quando o servidor realmente recebeu todos os cabeçalhos da solicitação, mas é possível que os dados ainda não tenham sido recebidos, por isso precisamos aguardar. O objeto de solicitação http (uma instância http.IncomingMessage) é na verdade um fluxo legível . Em fluxos legíveis sempre que um pedaço de dados chega, um evento é emitido (supondo que você tenha registrado um retorno de chamada) e quando todos os pedaços chegaram, um evento é emitido. Aqui está um exemplo de como você escuta os eventos: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)
Convertendo buffers em seqüências de caracteres
Se você tentar isso, notará que os pedaços são buffers . Se você não está lidando com dados binários e precisa trabalhar com strings, sugiro usar o método request.setEncoding que faz com que o fluxo emita strings interpretadas com a codificação especificada e lida com caracteres de vários bytes corretamente.
Pedaços de buffer
Agora você provavelmente não está interessado em cada pedaço por si só, portanto, nesse caso, provavelmente você deseja armazená-lo da seguinte maneira:
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)
Aqui é usado o Buffer.concat , que simplesmente concatena todos os buffers e retorna um grande buffer. Você também pode usar o módulo concat-stream, que faz o mesmo:
const http = require('http');
const concat = require('concat-stream');
http.createServer((request, response) => {
concat(request, data => {
console.log('Data: ', data);
});
}).listen(8080)
Analisando Conteúdo
Se você está tentando aceitar HTML formulários de apresentação POST com nenhum arquivo ou distribuindo ajax jQuery chamadas com o tipo de conteúdo padrão, em seguida, o tipo de conteúdo é application/x-www-form-urlencoded
com uft-8
codificação. Você pode usar o módulo querystring para desserializá-lo e acessar as propriedades:
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)
Se o seu tipo de conteúdo for JSON, você poderá simplesmente usar JSON.parse em vez de qs.parse .
Se você estiver lidando com arquivos ou lidando com o tipo de conteúdo com várias partes, nesse caso, você deve usar algo como formidável, que remove toda a dor de lidar com ele. Dê uma olhada nesta outra resposta minha, onde eu postei links e módulos úteis para conteúdo de várias partes.
Tubulação
Se você não deseja analisar o conteúdo, mas passá-lo para outro lugar, por exemplo, envie-o para outra solicitação http como dados ou salve-o em um arquivo. Sugiro canalizá-lo em vez de armazená- lo em buffer, pois será menos código, lida melhor com a contrapressão, será preciso menos memória e, em alguns casos, mais rápido.
Então, se você deseja salvar o conteúdo em um arquivo:
http.createServer((request, response) => {
request.pipe(fs.createWriteStream('./request'));
}).listen(8080)
Limitando a quantidade de dados
Como outras respostas observadas, lembre-se de que clientes mal-intencionados podem enviar uma quantidade enorme de dados para travar seu aplicativo ou encher sua memória, de modo a proteger, a fim de proteger as solicitações que emitem dados que ultrapassam um determinado limite. Se você não usar uma biblioteca para manipular os dados recebidos. Eu sugeriria usar algo como medidor de fluxo que pode abortar a solicitação se atingir o limite especificado:
limitedStream = request.pipe(meter(1e7));
limitedStream.on('data', ...);
limitedStream.on('end', ...);
ou
request.pipe(meter(1e7)).pipe(createWriteStream(...));
ou
concat(request.pipe(meter(1e7)), ...);
Módulos NPM
Enquanto eu descrevi acima sobre como você pode usar o corpo da solicitação HTTP, para simplesmente armazenar em buffer e analisar o conteúdo, sugiro o uso de um desses módulos em vez de implementar por conta própria, pois eles provavelmente irão lidar melhor com casos extremos. Para expressar, sugiro usar o analisador de corpo . Para o koa, há um módulo semelhante .
Se você não usa uma estrutura, o corpo é muito bom.
app.use(express.bodyParser());
.