Wie verarbeite ich POST-Daten in Node.js?

635

Wie extrahieren Sie Formulardaten ( form[method="post"]) und Datei-Uploads, die von der HTTP- POSTMethode in Node.js gesendet wurden ?

Ich habe die Dokumentation gelesen, gegoogelt und nichts gefunden.

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

Gibt es eine Bibliothek oder einen Hack?

Ming-Tang
quelle

Antworten:

551

Wenn Sie Express verwenden (leistungsstarke, erstklassige Webentwicklung für Node.js), können Sie Folgendes tun:

HTML:

<form method="post" action="/">
    <input type="text" name="user[name]">
    <input type="text" name="user[email]">
    <input type="submit" value="Submit">
</form>

API-Client:

fetch('/', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        user: {
            name: "John",
            email: "[email protected]"
        }
    })
});

Node.js: (seit 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: (für 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
quelle
45
Die Funktionalität befindet sich tatsächlich im BodyParser-Modul in connect, wenn Sie einen Einstiegspunkt auf einer niedrigeren Ebene verwenden möchten.
Julian Birch
14
Ich bin verwirrt. Wie entspricht name = "user [email]" request.body.email?
sbose
36
Gott!! Ich werde wütend, wenn ich 3 Dokumente gleichzeitig für dasselbe Framework lesen muss: / nodejs.org/api/http.html , senchalabs.org/connect & expressjs.com/guide.html
Salman von Abbas
15
Das hat bei mir nicht funktioniert, bis ich hinzugefügt habe app.use(express.bodyParser());.
Pettys
13
Express ist zu knoten, was jQuery zu clientseitigem JS ist. Jedes Mal, wenn ich die Google-Hilfe für den Knoten google, erhalte ich diese lahmen "Express verwenden!" Antworten. Ist es wirklich so schwierig, Post-Daten zu analysieren, dass die Installation eines gesamten Web-Frameworks gerechtfertigt ist?
Shawn Whinnery
710

Sie können das querystringModul verwenden:

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

Wenn Sie beispielsweise ein inputFeld mit Namen haben age, können Sie mit der Variablen darauf zugreifen post:

console.log(post.age);
Casey Chu
quelle
8
@thejh Hm, das ist ein guter Punkt. Es sollte jedoch nicht schwierig sein, das hinzuzufügen, deshalb werde ich es aus dem Beispiel herauslassen, um die Dinge einfach zu halten.
Casey Chu
72
Die Webserverentwicklung von node.js ist von Middlewarez geplagt, bei denen Sie sie stundenlang studieren müssen, um Minuten an Codierung zu sparen. Geschweige denn die spärliche Dokumentation, die fast alle bieten. Und Ihre Bewerbung stützt sich letztendlich auf die Kriterien anderer Personen, nicht auf Ihre. Plus eine beliebige Anzahl von Leistungsproblemen.
Juan Lanus
4
var POST = qs.parse(body); // use POST Nur für Noobs wie mich: Wenn der Name des Eingabetextfelds "Benutzer" ist, Post.userwerden die Daten dieses Feldes angezeigt. zBconsole.log(Post.user);
Michael Moeller
5
Sie können auch den readableRückruf verwenden, anstatt die Daten in eine Textzeichenfolge zu integrieren. Sobald es abgefeuert ist, ist die Leiche verfügbar durchrequest.read();
Thomas Fankhauser
4
Beachten Sie, req.connection.destroy(); dass die Rückrufe nicht ausgeführt werden können! Zum Beispiel wird der "on end" -Rückruf mit dem abgeschnittenen Körper ausgeführt! Dies ist wahrscheinlich nicht das, was Sie wollen ...
Collimarco
148

Stellen Sie sicher, dass die Verbindung unterbrochen wird, wenn jemand versucht, Ihren RAM zu überfluten!

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
quelle
52
Sie können auch HTTP 413-Fehlercode (Request Entity Too Large) zurückgeben
neoascetic
1
@SSHThis: Nein, es ist 1 * 10 ^ 6 = 1000000.
thejh
@tq: in diesem Fall POST [Name] (zB POST ["foo"]).
Thejh
2
var POST = qs.parse(body); // use POST Nur für Noobs: Wenn der Name des Eingabetextfelds "Benutzer" lautet, zeigt Post.user die Daten dieses Felds an. zB console.log (Post.user);
Michael Moeller
2
Kann mir jemand helfen, wenn ich {'Name': 'Joe'} poste, bekomme ich {{'Name': 'Joe'}: ''} nach qs.Parse (POST) ...
Matt Canty
118

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-urlencodedmit uft-8Codierung. 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.

Farid Nouri Neshat
quelle
Danke, ich habe Ihren Code verwendet und mysteriöse doppelte Nachrichten erhalten. Könnte es sein, dass die Variable requestwiederverwendet wird und request.on('end')mehrmals aufgerufen wurde? Wie kann ich das vermeiden?
Yan King Yin
Ich kann nicht sagen warum, ohne Ihren Code zu sehen. Beachten Sie, dass für jede Anfrage request.on('end', ...)aufgerufen wird.
Farid Nouri Neshat
Es hat wahrscheinlich nichts mit Ihrem Code zu tun, ich mache vom Server gesendete Ereignisse und habe es möglicherweise vermasselt ... Ihr Code funktioniert einwandfrei, trotzdem danke :)
Yan King Yin
Wie wirkt sich dies auf die Leistung im Vergleich zur Verarbeitung einer GET-Anforderung ohne 'End'-Handler aus, dh ohne Pufferung von Chunks?
JSON
1
Dies hier ist die beste Antwort auf die Frage. 🧐
Montrealist
103

Hier ist ein sehr einfacher No-Framework-Wrapper, der auf den anderen hier veröffentlichten Antworten und Artikeln basiert:

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

Anwendungsbeispiel:

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
quelle
Sollte diese Prüfung nicht in eine separate Middleware verschoben werden, damit bei allen Post- / Put-Anfragen nach zu großen Anforderungen gesucht werden kann
Pavel Nikolov
@PavelNikolov Dies ist hauptsächlich für schnelle und schmutzige Jobs gedacht, andernfalls ist es wahrscheinlich besser, Express zu verwenden, wie es die hier akzeptierte Antwort empfiehlt (die sich wahrscheinlich auch um die Verwaltung großer Anfragen kümmert). Fühlen Sie sich frei, es zu modifizieren und nach Ihren Wünschen zu "gabeln".
Mahn
Was ist mit der .read () -Methode? Wird das vom http-Modul nicht unterstützt? Z.B. response.read ()
BT
Hey, nur neugierig - warum haben Sie die Nutzdaten in das Antwortobjekt (response.post) anstatt in das Anforderungsobjekt gestellt?
Jotham
@Jotham gute Frage ... Ich habe keine Ahnung, warum ich das nicht früher bemerkt habe, aber es gibt keinen Grund, warum es response.posteher sein sollte als das logischere request.post. Ich habe den Beitrag aktualisiert.
Mahn
83

Es ist sauberer, wenn Sie Ihre Daten in JSON codieren und dann an Node.js senden.

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));
        });
    }
}
Lewis
quelle
1
Das hat bei mir funktioniert. Es stellte sich heraus, dass die anderen Lösungen eine Zeichenfolge zurückgaben, die wie JSON aussah, aber nicht analysiert wurde. Statt qs.parse(), JSON.parse()drehte den Körper in etwas Brauchbares. Beispiel: var post = JSON.parse(body);Dann greifen Sie mit auf die Daten zu post.fieldname. (Moral der Geschichte, wenn Sie verwirrt sind über das, was Sie sehen, vergessen Sie nicht typeof!)
wmassingham
12
Beachten Sie jedoch, dass Sie versuchen müssen, die Funktion JSON.parse abzufangen, denn wenn ich Ihre Anwendung zum Absturz bringen möchte, senden Sie einfach einen Textkörper mit Rohtext.
Ecarrizo
Sie sollten verwenden request.setEncoding, damit dies ordnungsgemäß funktioniert. Andernfalls werden Nicht-ASCII-Zeichen möglicherweise nicht ordnungsgemäß verarbeitet.
Farid Nouri Neshat
37

Für alle, die sich fragen, wie man diese triviale Aufgabe erledigt, ohne ein Webframework zu installieren, habe ich es geschafft, dies zusammenzufassen. Kaum produktionsbereit, aber es scheint zu funktionieren.

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);
        })
    }
}
Shawn Whinnery
quelle
Endlich eine VOLLSTÄNDIGE ARBEITSLÖSUNG für dieses seltsame Problem. Auch die vorherige Antwort hat mir sehr geholfen zu verstehen, warum die Anfrage zu Beginn des Rückrufs keine Daten enthielt. Vielen Dank!
Luis-Br
3
1) Diese Antwort setzt voraus, dass die Daten eine Zeichenfolge sind. Schlechte Annahme im Allgemeinen. 2) Diese Antwort setzt voraus, dass Daten in einem Block ankommen. Andernfalls führt die Aufteilung durch '=' zu einem unvorhersehbaren Ergebnis. Schlechte Annahme im Allgemeinen.
Konstantin
@Konstantin Tatsächlich geht diese Antwort davon aus, dass die Daten ein Puffer sind. Überprüfen Sie dies heraus. stackoverflow.com/questions/14551194/… Auch dies. millermedeiros.github.io/mdoc/examples/node_api/doc/…
Shawn Whinnery
16

Sie können body-parserdie Body-Parsing-Middleware von Node.js verwenden.

Erste Ladung body-parser

$ npm install body-parser --save

Ein Beispielcode

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

Weitere Dokumentation finden Sie hier

Quellcode
quelle
9

So können Sie es tun, wenn Sie Node-Formidable verwenden :

var formidable = require("formidable");

var form = new formidable.IncomingForm();
form.parse(request, function (err, fields) {
    console.log(fields.parameter1);
    console.log(fields.parameter2);
    // ...
});
Dmitry Efimenko
quelle
Ich habe ein Problem mit dem Pfad, wenn ich versuche, den Pfad oder den Pfad + Namen zu verwenden, um mit lwip.open auf die Datei zuzugreifen (Pfad oder Pfad + Name. Ich
erhalte
7

Wenn Sie reine Node.js bevorzugen, können Sie POST-Daten wie folgt extrahieren:

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

Oleksii Trekhleb
quelle
6

1) 'body-parser'Von npm installieren .

2) Dann in Ihrer App.ts.

var bodyParser = require('body-parser');

3) dann musst du schreiben

app.use(bodyParser.json())

im app.ts Modul

4) Denken Sie daran, dass Sie einschließen

app.use(bodyParser.json())

oben oder vor einer Moduldeklaration.

Ex:

app.use(bodyParser.json())
app.use('/user',user);

5) Dann verwenden

var postdata = req.body;
Er Shubham Patidar
quelle
5

Wenn Sie Ihre Daten nicht zusammen mit dem dataRückruf aufteilen möchten, können Sie den Rückruf immer folgendermaßen verwenden 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
});

Dieser Ansatz ändert die eingehende Anfrage, aber sobald Sie Ihre Antwort beendet haben, wird die Anfrage durch Müll gesammelt, sodass dies kein Problem darstellen sollte.

Ein fortgeschrittener Ansatz wäre, zuerst die Körpergröße zu überprüfen, wenn Sie Angst vor riesigen Körpern haben.

Thomas Fankhauser
quelle
Bequemer Weg, aber wie können Sie "zuerst die Körpergröße überprüfen" auf eine Weise, die nicht durch eine böswillige Anfrage getäuscht werden kann?
Doug65536
requestist ein normaler node.js-Stream, sodass Sie request.headersdie Body-Länge überprüfen und die Anforderung bei Bedarf abbrechen können.
Thomas Fankhauser
1
@ThomasFankhauser Die Körperlänge im Header ist möglicherweise nicht der richtige Wert oder sogar vorhanden. Der richtige Weg ist, wenn der Körper ankommt und Sie ihn puffern, überprüfen Sie die Größe, um sicherzustellen, dass er das Limit nicht überschreitet.
Farid Nouri Neshat
4

Es gibt mehrere Möglichkeiten, dies zu tun. Der schnellste Weg, den ich kenne, ist jedoch die Verwendung der Express.js-Bibliothek mit 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);

Das kann für Zeichenfolgen funktionieren, aber ich würde stattdessen bodyParser.urlencoded in bodyParser.json ändern, wenn die POST-Daten ein JSON-Array enthalten.

Weitere Informationen: http://www.kompulsa.com/how-to-accept-and-parse-post-requests-in-node-js/

nikodean2
quelle
4

Sie müssen die POSTDaten in Blöcken mit empfangenrequest.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)

Sie sollten in Betracht ziehen, an der angegebenen Position eine Größenbeschränkung hinzuzufügen, wie dies vorgeschlagen wird .

Zaz
quelle
Ist dies eher anfällig für einen Slow-Loris-Angriff?
Nodejs ist weniger anfällig für Slow-Loris als z. B. PHP, da nicht um jede http-Verbindung ein großes Sitzungsobjekt erstellt wird. Es scheint jedoch, dass dieser Code immer noch eine Slow-Loris-Sicherheitsanfälligkeit verursachen könnte. Dies könnte mit einem verhindert werden setTimeout, der die Verbindung nach einer bestimmten Zeit beendet, wenn die vollständige Anforderung nicht in diesem Fenster empfangen wird.
Gershom
4

Express v4.17.0

app.use(express.urlencoded( {extended: true} ))
Anteliebe
quelle
3

Wenn Sie mit Express.js , bevor Sie auf die req.body zugreifen können, müssen Sie Middleware bodyParser hinzufügen:

app.use(express.bodyParser());

Dann können Sie fragen

req.body.user
PatricioS
quelle
Die meiste Middleware (wie bodyParser) wird nicht mehr mit Express gebündelt und muss separat installiert werden. Siehe die Antwort von @ nikodean2 oben für eine aktuellere Antwort
Jeff Collier
app.use (bodyParser ()); funktioniert, gibt mir aber veraltete rote Fehlermeldungen
Chris Allinson
2

Und wenn Sie nicht das gesamte Framework wie Express verwenden möchten, sondern auch verschiedene Arten von Formularen benötigen, einschließlich Uploads, ist Formalin möglicherweise eine gute Wahl.

Es ist in den Modulen von Node.j aufgeführt

Pavel Koryagin
quelle
1

Ich habe ein Video gefunden, in dem erklärt wird, wie dies erreicht werden kann: https://www.youtube.com/watch?v=nuw48-u3Yrg

Es verwendet das Standardmodul "http" zusammen mit den Modulen "querystring" und "stringbuilder". Die Anwendung nimmt zwei Zahlen (unter Verwendung von zwei Textfeldern) von einer Webseite und gibt beim Senden die Summe dieser beiden zurück (zusammen mit dem Beibehalten der Werte in den Textfeldern). Dies ist das beste Beispiel, das ich irgendwo anders finden könnte.

Zugehöriger Quellcode:

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
quelle
1

Für diejenigen, die einen rohen binären POST-Upload ohne Codierungsaufwand verwenden, können Sie Folgendes verwenden:

Klient:

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

Server:

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
quelle
1

Sie können die Express- Middleware verwenden, in die jetzt ein Body-Parser integriert ist. Dies bedeutet, dass Sie lediglich Folgendes tun müssen:

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

Dieses Codebeispiel ist ES6 mit Express 4.16.x.

Großes Geld
quelle
0

Sie können Post-Parameter ohne Express extrahieren.

1: nmp install multiparty

2: Mehrparteien importieren. wievar 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: und HTML FORM IS.

<form method=POST enctype=multipart/form-data>
<input type=text name=userfile1><br>
<input type=submit>
</form>

Ich hoffe das wird für dich funktionieren. Vielen Dank.

Maneesh Singh
quelle
0

Begrenzen Sie die POST-Größe und vermeiden Sie eine Überflutung Ihrer Knoten-App. Es gibt eine große Roh-Körper - Modul, geeignet sowohl für Express- und verbinden, die Sie nach Größe und Länge begrenzen Anfrage helfen können.

EricSonaron
quelle
0

Wenn es sich um einen Datei-Upload handelt, sendet der Browser ihn normalerweise als "multipart/form-data"Inhaltstyp. Sie können dies in solchen Fällen verwenden

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

Referenz 1

Referenz 2

user3526
quelle
0

Auf Formularfeldern wie diesen

   <input type="text" name="user[name]" value="MyName">
   <input type="text" name="user[email]" value="[email protected]">

Einige der oben genannten Antworten schlagen fehl, da sie nur flache Daten unterstützen.

Im Moment verwende ich die Casey Chu-Antwort, aber mit dem "qs" anstelle des "querystring" -Moduls. Dies ist auch das Modul, das "Body-Parser" verwendet. Wenn Sie also verschachtelte Daten möchten, müssen Sie qs installieren.

npm install qs --save

Ersetzen Sie dann die erste Zeile wie folgt:

//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.
        });
    }
}
Geza Turi
quelle
0

Sie können die POST-Anfrage einfach senden und abrufen, indem Sie "Request - Simplified HTTP Client" und Javascript Promise verwenden.

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
quelle
0

Sie müssen bodyParser () verwenden, wenn die Formulardaten in req.body verfügbar sein sollen. body-parser analysiert Ihre Anfrage und konvertiert sie in ein Format, aus dem Sie auf einfache Weise relevante Informationen extrahieren können, die Sie möglicherweise benötigen.

Angenommen, Sie haben ein Anmeldeformular an Ihrem Frontend. Sie füllen es aus und fordern den Server auf, die Details irgendwo zu speichern.

Das Extrahieren von Benutzername und Passwort aus Ihrer Anfrage ist so einfach wie unten, wenn Sie Body-Parser verwenden.

………………………………………………….

var loginDetails = {

username : request.body.username,

password : request.body.password

};
Rubin Bhandari
quelle
0

EIN LINER ohne MIDDLEWARE
Wenn Sie folgende Daten veröffentlichen,
'name':'ABC'
können Sie diese mit dem folgenden Liner analysieren:

require('url').parse(req.url, true).query.name
Hardik Trivedi
quelle