Viele Antworten hier sind keine guten Praktiken mehr oder erklären nichts mehr, deshalb schreibe ich das hier.
Grundlagen
Wenn der Rückruf von http.createServer aufgerufen wird, hat der Server tatsächlich alle Header für die Anforderung empfangen, aber es ist möglich, dass die Daten noch nicht empfangen wurden, sodass wir darauf warten müssen. Das http-Anforderungsobjekt (eine http.IncomingMessage-Instanz) ist tatsächlich ein lesbarer Stream . In lesbaren Streams wird bei jedem Eintreffen eines Datenblocks ein Ereignis ausgegeben (vorausgesetzt, Sie haben einen Rückruf registriert), und wenn alle Blöcke angekommen sind, wird ein Ereignis ausgegeben. Hier ist ein Beispiel, wie Sie die Ereignisse anhören: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)
Puffer in Strings konvertieren
Wenn Sie dies versuchen, werden Sie feststellen, dass die Chunks Puffer sind . Wenn Sie nicht mit Binärdaten arbeiten und stattdessen mit Zeichenfolgen arbeiten müssen, empfehle ich die Verwendung von request.setEncoding Methode, die bewirkt, dass der Stream Zeichenfolgen , die mit der angegebenen Codierung interpretiert werden, und Multi-Byte-Zeichen ordnungsgemäß verarbeitet.
Chunks puffern
Jetzt interessieren Sie sich wahrscheinlich nicht für jeden Block für sich. In diesem Fall möchten Sie ihn wahrscheinlich wie folgt puffern:
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)
Hier wird Buffer.concat verwendet, das einfach alle Puffer verkettet und einen großen Puffer zurückgibt . Sie können auch das Concat-Stream-Modul verwenden, das dasselbe tut:
const http = require('http');
const concat = require('concat-stream');
http.createServer((request, response) => {
concat(request, data => {
console.log('Data: ', data);
});
}).listen(8080)
Analysieren von Inhalten
Wenn Sie versuchen , HTML - Formulare POST Vorlage ohne Dateien oder Gabe zu akzeptieren jQuery Ajax - Anrufe mit dem Standardinhaltstyp, dann ist der Inhaltstyp application/x-www-form-urlencoded
mit uft-8
Codierung. Sie können das Querystring-Modul verwenden, um es zu de-serialisieren und auf die Eigenschaften zuzugreifen:
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)
Wenn Ihr Inhaltstyp stattdessen JSON ist, können Sie einfach JSON.parse anstelle von qs.parse verwenden .
Wenn Sie sich mit Dateien beschäftigen oder mit mehrteiligen Inhaltstypen umgehen, sollten Sie in diesem Fall so etwas wie beeindruckend verwenden, das alle Schmerzen beim Umgang damit beseitigt. Schauen Sie sich diese andere Antwort von mir an, in der ich hilfreiche Links und Module für mehrteilige Inhalte veröffentlicht habe.
Rohrleitungen
Wenn Sie den Inhalt nicht analysieren, sondern an eine andere Stelle weitergeben möchten, z. B. als Daten an eine andere http-Anforderung senden oder in einer Datei speichern möchten, empfehle ich, ihn weiterzuleiten, anstatt ihn zu puffern, da er geringer ist Code, behandelt den Gegendruck besser, benötigt weniger Speicher und ist in einigen Fällen schneller.
Wenn Sie den Inhalt in einer Datei speichern möchten:
http.createServer((request, response) => {
request.pipe(fs.createWriteStream('./request'));
}).listen(8080)
Begrenzung der Datenmenge
Wie andere Antworten bereits festgestellt haben, sollten Sie bedenken, dass böswillige Clients Ihnen möglicherweise eine große Datenmenge senden, um Ihre Anwendung zum Absturz zu bringen oder Ihren Speicher zu füllen, um sicherzustellen, dass Sie Anfragen löschen, die Daten ausgeben, die ein bestimmtes Limit überschreiten. Wenn Sie keine Bibliothek verwenden, um die eingehenden Daten zu verarbeiten. Ich würde vorschlagen, so etwas wie einen Stream-Meter zu verwenden, der die Anfrage abbrechen kann, wenn das angegebene Limit erreicht ist:
limitedStream = request.pipe(meter(1e7));
limitedStream.on('data', ...);
limitedStream.on('end', ...);
oder
request.pipe(meter(1e7)).pipe(createWriteStream(...));
oder
concat(request.pipe(meter(1e7)), ...);
NPM-Module
Während ich oben beschrieben habe, wie Sie den HTTP-Anforderungshauptteil zum einfachen Puffern und Parsen des Inhalts verwenden können, schlage ich vor, eines dieser Module zu verwenden, anstatt es selbst zu implementieren, da sie wahrscheinlich Randfälle besser behandeln. Für Express empfehle ich Body-Parser . Für Koa gibt es ein ähnliches Modul .
Wenn Sie kein Framework verwenden, ist der Körper ziemlich gut.