Wie rufe ich POST-Abfrageparameter ab?

768

Hier ist meine einfache Form:

<form id="loginformA" action="userlogin" method="post">
    <div>
        <label for="email">Email: </label>
        <input type="text" id="email" name="email"></input>
    </div>
<input type="submit" value="Submit"></input>
</form>

Hier ist mein Express.js /Node.js Code:

app.post('/userlogin', function(sReq, sRes){    
    var email = sReq.query.email.;   
}

Ich habe es versucht sReq.query.emailoder sReq.query['email']oder sReq.params['email']usw. Keiner von ihnen funktioniert. Sie alle kehren zurück undefined.

Wenn ich zu einem Get-Anruf wechsle, funktioniert das, also ... eine Idee?

Murvinlai
quelle
33
SICHERHEIT : Jeder, bodyParser()der die Antworten hier verwendet, sollte auch die Antwort von @SeanLynch unten
FelipeAls
Verwenden Sie das Body-Parser- Modul. Hier sind einige nützliche Anwendungsbeispiele für Body-Parser
Drorw

Antworten:

1251

Ab Express 4.16.0 haben sich die Dinge erneut geändert . Sie können sie jetzt express.json()und express.urlencoded()genau wie in Express 3.0 verwenden .

Dies war ab Express 4.0 bis 4.15 anders :

$ npm install --save body-parser

und dann:

var bodyParser = require('body-parser')
app.use( bodyParser.json() );       // to support JSON-encoded bodies
app.use(bodyParser.urlencoded({     // to support URL-encoded bodies
  extended: true
})); 

Der Rest ist wie in Express 3.0 :

Zuerst müssen Sie Middleware hinzufügen, um die Post-Daten des Körpers zu analysieren.

Fügen Sie eine oder beide der folgenden Codezeilen hinzu:

app.use(express.json());       // to support JSON-encoded bodies
app.use(express.urlencoded()); // to support URL-encoded bodies

Verwenden Sie dann in Ihrem Handler das req.bodyObjekt:

// assuming POST: name=foo&color=red            <-- URL encoding
//
// or       POST: {"name":"foo","color":"red"}  <-- JSON encoding

app.post('/test-page', function(req, res) {
    var name = req.body.name,
        color = req.body.color;
    // ...
});

Beachten Sie, dass die Verwendung von express.bodyParser()nicht empfohlen wird.

app.use(express.bodyParser());

...ist äquivalent zu:

app.use(express.json());
app.use(express.urlencoded());
app.use(express.multipart());

Es bestehen Sicherheitsbedenken. Daher express.multipart()ist es besser, die Unterstützung für die spezifischen Codierungstypen, die Sie benötigen, explizit hinzuzufügen. Wenn Sie eine mehrteilige Codierung benötigen (um beispielsweise das Hochladen von Dateien zu unterstützen), sollten Sie diese lesen .

Drew Noakes
quelle
76
Wenn diese Antwort nicht richtig funktioniert, stellen Sie sicher, dass Sie den content-typeHeader gesetzt haben, zum Beispiel:curl -d '{"good_food":["pizza"]}' -H 'content-type:application/json' "http://www.example.com/your_endpoint"
SooDesuNe
6
Was ist der Unterschied zwischen dem Posten eines Formulars mit Name / Wert-Paaren und dem Posten eines JSON-Körpers? Erscheinen beide in req.body?
Chovy
7
@chovy Ja, das tun sie. bodyParserabstrahiert JSON-, URL-codierte und mehrteilige Daten in das req.bodyObjekt.
Kristján
7
Dieser Code gab mir Fehler, da Middleware nicht mehr mit Express gebündelt ist. Sie müssen Body-Parser verwenden: github.com/senchalabs/connect#middleware
araneae
11
Zum Lesen von json mit Express 4 ist nur die app.use(require('body-parser').json())Zeile ausreichend. Und dann können Sie die JSON-Daten aus dem Body-Objekt Ihrer Anfrage lesen, dh req.bodyaus einer Routendefinition.
Martin Carel
90

Sicherheitsbedenken bei Verwendung von express.bodyParser ()

Während alle anderen Antworten zur Zeit mit dem empfehlen express.bodyParser()Middleware, das ist eigentlich ein Wrapper um die express.json(), express.urlencoded()und express.multipart()Middle ( http://expressjs.com/api.html#bodyParser ). Das Parsen von Formularanforderungskörpern erfolgt durch die express.urlencoded()Middleware und ist alles, was Sie benötigen, um Ihre Formulardaten für req.bodyObjekte verfügbar zu machen.

Aus Sicherheitsgründen, wie express.multipart()/ connect.multipart()temporäre Dateien für alle hochgeladenen Dateien erstellt werden (und nicht durch Müll gesammelt werden), wird jetzt empfohlen , den express.bodyParser()Wrapper nicht zu verwenden, sondern nur die von Ihnen benötigten Middlewares.

Hinweis: connect.bodyParser()Wird in Kürze aktualisiert und enthält nur urlencodedund jsonwenn Connect 3.0 veröffentlicht wird (was Express erweitert).


Also kurz gesagt, anstatt ...

app.use(express.bodyParser());

...du solltest benutzen

app.use(express.urlencoded());
app.use(express.json());      // if needed

Wenn Sie mehrteilige Formulare (Datei-Uploads) verarbeiten müssen, verwenden Sie eine Bibliothek oder Middleware eines Drittanbieters wie Multiparty, Busboy, Dicer usw.

Sean Lynch
quelle
Unter der Frage wurde ein Kommentar hinzugefügt, damit mehr Menschen Ihre Bedenken und Ratschläge sehen. Würden andere im Andrew Kelley-Blogbeitrag (noch) beschriebene Lösungen Ihrer Meinung nach relevant sein? (Ich frage nur nach anderen, meine Bedürfnisse sind nur für interne Tools ^^)
FelipeAls
@FelipeAls - Ja, und ich wollte auch auf Andrews Beitrag verweisen. Jeder dieser Vorschläge (unter Berücksichtigung der jeweiligen Nachteile) ist relevant.
Sean Lynch
Sobald Connect 3.0 ohne Einbeziehung multipart()als Teil von veröffentlicht wurde bodyParser(), bodyParser()wird es wieder "sicher". Sie müssen jedoch die mehrteilige Unterstützung mithilfe einer Drittanbieter-Bibliothek explizit aktivieren.
Sean Lynch
84

Hinweis : Diese Antwort gilt für Express 2. Siehe hier für Express 3.

Wenn Sie Connect / Express verwenden, sollten Sie die bodyParser-Middleware verwenden : Sie wird im Expressjs-Handbuch beschrieben .

// example using express.js:
var express = require('express')
  , app = express.createServer();
app.use(express.bodyParser());
app.post('/', function(req, res){
  var email = req.param('email', null);  // second parameter is default
});

Hier ist die ursprüngliche Nur-Verbindung-Version:

// example using just connect
var connect = require('connect');
var url = require('url');
var qs = require('qs');
var server = connect(
  connect.bodyParser(),
  connect.router(function(app) {
    app.post('/userlogin', function(req, res) {
      // the bodyParser puts the parsed request in req.body.
      var parsedUrl = qs.parse(url.parse(req.url).query);
      var email = parsedUrl.email || req.body.email;;
    });
  })
);

Sowohl der Querystring als auch der Body werden mithilfe der Parameterbehandlung ( qs) im Rails-Stil und nicht mithilfe der Bibliothek auf niedriger Ebenequerystring analysiert . Um wiederholte Parameter mit zu analysieren qs, muss der Parameter in Klammern stehen : name[]=val1&name[]=val2. Es werden auch verschachtelte Karten unterstützt. Zusätzlich zum Parsen von HTML-Formularübermittlungen kann der bodyParser JSON-Anforderungen automatisch analysieren.

Bearbeiten : Ich habe auf express.js nachgelesen und meine Antwort geändert, um für Benutzer von Express natürlicher zu sein.

Yonran
quelle
Hmm ok Ich versuche den BodyParser (). Der Doc sagt, ich kann es von req.query () bekommen, aber ich habe nichts. das ist sehr komisch Ich habe kein Problem mit Get tho.
Murvinlai
3
Nein, req.query ist NUR die GET-Parameter. Sie erhalten die POST-Daten über req.body. Die Funktion req.params () enthält beide.
Yonran
Ein streunender Klick hat diese Antwort versehentlich herabgestuft, ohne dass ich es bemerkt habe! Jetzt kann ich es mit StackOverflow nicht mehr ändern. Esp. frustrierend, da dies hilfreich war ... Ich habe eine weitere Ihrer guten Antworten positiv bewertet, nach denen ich nicht explizit gesucht habe, um dies auszugleichen. :)
HostileFork sagt nicht vertrauen SE
33

Dies ist der Fall, wenn Sie die gepostete Abfrage ohne Middleware erstellen möchten:

app.post("/register/",function(req,res){
    var bodyStr = '';
    req.on("data",function(chunk){
        bodyStr += chunk.toString();
    });
    req.on("end",function(){
        res.send(bodyStr);
    });

});

Das wird dies an den Browser senden

email=emailval&password1=pass1val&password2=pass2val

Es ist wahrscheinlich besser, Middleware zu verwenden, damit Sie dies nicht in jeder Route immer wieder schreiben müssen.

med116
quelle
3
sooo ... praktisch, für diejenigen, die sich nicht auf eine Bibliothek verlassen wollen, die früher oder später veraltet sein wird
Daniel
Sie könnten leicht Ihre eigene Middleware bauen
Maioman
Dies ist eine gute Antwort, aber warum gibt es zusätzlichen Text "---------------------------- 359856253150893337905494 Inhaltsdisposition: Formulardaten; Name = "fullName" Ram ---------------------------- 359856253150893337905494-- "Ich möchte diese Nummer nicht.
Nawaraj
25

Hinweis für Express 4-Benutzer:

Wenn Sie versuchen, app.use(express.bodyParser());in Ihre App zu integrieren, wird beim Versuch, Ihren Express-Server zu starten, die folgende Fehlermeldung angezeigt:

Fehler: Die meiste Middleware (wie bodyParser) wird nicht mehr mit Express gebündelt und muss separat installiert werden. Weitere Informationen finden Sie unter https://github.com/senchalabs/connect#middleware .

Sie müssen das Paket body-parserseparat von npm installieren und dann Folgendes verwenden (Beispiel von der GitHub-Seite ):

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

var app = express();

app.use(bodyParser());

app.use(function (req, res, next) {
  console.log(req.body) // populated!
  next();
})
mplewis
quelle
Vielen Dank für diese Information. Ich habe mir die Haare ausgezogen, um mit der neuen Art der Verwendung von bodyParser fertig zu werden! Dies war ein großer Durchbruch - wirklich zu schätzen
Tommy
1
heplp: body-parser veralteter bodyParser: benutze einzelne json / urlencodierte Middlewares
Mohammad Faizan Khan
19

In irgendeiner Form:

<form action='/somepath' method='post'>
   <input type='text' name='name'></input>
</form>

Mit Express

app.post('/somepath', function(req, res) {

    console.log(JSON.stringify(req.body));

    console.log('req.body.name', req.body['name']);
});

Ausgabe:

{"name":"x","description":"x"}
req.param.name x
David
quelle
6
hat nicht für mich gearbeitet. müssen app.use (express.bodyParser ()) verwenden;
Cawecoy
@cawecoy absolut richtig hier, aber express.bodyParser () funktioniert nicht so gut für mich, es ist veraltet
Mohammad Faizan Khan
@MohammadFaizankhan es war eine experimentelle Arbeit, ich habe keinen Express mehr benutzt, kann jetzt nicht helfen. Google es für ähnliche Funktionen wie express.bodyParser (). Viel Glück!
Cawecoy
16

Backend:

import express from 'express';
import bodyParser from 'body-parser';

const app = express();
app.use(bodyParser.json()); // add a middleware (so that express can parse request.body's json)

app.post('/api/courses', (request, response) => {
  response.json(request.body);
});

Vorderes Ende:

fetch("/api/courses", {
  method: 'POST',
  body: JSON.stringify({ hi: 'hello' }), // convert Js object to a string
  headers: new Headers({ "Content-Type": "application/json" }) // add headers
});
Seen sind
quelle
15
app.use(express.bodyParser());

Dann können Sie auf app.postAnfrage Post-Werte über erhalten req.body.{post request variable}.

Chinthaka Senanayaka
quelle
Ist Ihre Post-Request-Variable hier die ID des betreffenden Eingabefelds oder das gesamte Formular oder was?
Eogcloud
2
express.bodyParser () ist veraltet. Aktualisieren Sie Ihre Antwort
Mohammad Faizan Khan
15

Update für Express 4.4.1

Folgende Middleware wird aus Express entfernt.

  • bodyParser
  • json
  • urlencodiert
  • mehrteilig

Wenn Sie die Middleware direkt wie in Express 3.0 verwenden. Sie erhalten folgende Fehlermeldung:

Error: Most middleware (like urlencoded) is no longer bundled with Express and 
must be installed separately.


Um diese Middleware nutzen zu können, müssen Sie jetzt für jede Middleware separat npm ausführen .

Da bodyParser als veraltet markiert ist, empfehle ich die folgende Methode, um json, urlencode und mehrteiligen Parser wie formidable connect-multiparty zu verwenden. (Multipart Middleware ist ebenfalls veraltet).

Denken Sie auch daran, dass beim Definieren von urlencode + json die Formulardaten nicht analysiert werden und req.body undefiniert ist. Sie müssen ein Middleware-Handle für die mehrteilige Anforderung definieren.

var urlencode = require('urlencode');
var json = require('json-middleware');
var multipart = require('connect-multiparty');
var multipartMiddleware = multipart();

app.use(json);
app.use(urlencode);
app.use('/url/that/accepts/form-data', multipartMiddleware);
Yeelan
quelle
Ich denke, das ist wirklich eine schlechte Feature-Aktualisierung
Mohammad Faizan Khan
Nur um der Körperanalyse willen muss ich viel Code machen. Was zum
Teufel
1
Ich musste ".middleware ()" hinzufügen, um ('json-middleware') zu benötigen, damit dies funktioniert.
DustinB
8

Für Express 4.1 und höher

Da die meisten Antworten Express, bodyParser, connect verwenden; wo mehrteilig veraltet ist. Es gibt eine sichere Möglichkeit, Post-Multipart-Objekte einfach zu senden.

Multer kann als Ersatz für connect.multipart () verwendet werden.

So installieren Sie das Paket

$ npm install multer

Laden Sie es in Ihre App:

var multer = require('multer');

Fügen Sie es dann zusammen mit der anderen Form, die die Middleware analysiert, zum Middleware-Stapel hinzu.

app.use(express.json());
app.use(express.urlencoded());
app.use(multer({ dest: './uploads/' }));

connect.json () behandelt application / json

connect.urlencoded () behandelt application / x-www-form-urlencoded

multer () verarbeitet mehrteilige / Formulardaten

Lalit Umbarkar
quelle
8

Ich habe genau nach diesem Problem gesucht. Ich habe alle oben genannten Ratschläge befolgt, aber req.body hat immer noch ein leeres Objekt {} zurückgegeben. In meinem Fall war es genauso einfach wie das falsche HTML.

Stellen Sie im HTML Ihres Formulars sicher, dass Sie das 'name'Attribut nicht nur in Ihren Eingabe-Tags verwenden 'id'. Ansonsten wird nichts analysiert.

<input id='foo' type='text' value='1'/>             // req = {}
<input id='foo' type='text' name='foo' value='1' /> // req = {foo:1}

Mein idiotischer Fehler ist dein Vorteil.

cwingrav
quelle
Selbes Problem hier. Aber ich habe von Anfang an das Namensattribut verwendet. Mal sehen, was das Problem ist.
Saif Al Falah
6

Sie sollten app.use (express.bodyParser ()) nicht verwenden . BodyParser ist eine Vereinigung von json + urlencoded + mulitpart. Sie sollten dies nicht verwenden, da Multipart in Connect 3.0 entfernt wird.

Um dies zu beheben, können Sie Folgendes tun:

app.use(express.json());
app.use(express.urlencoded());

Es ist sehr wichtig zu wissen, dass app.use (app.router) nach dem json und urlencoded verwendet werden sollte, sonst funktioniert es nicht!

HenioJR
quelle
4

Anforderungs-Streaming hat bei mir funktioniert

req.on('end', function() {
    var paramstring = postdata.split("&");
});

var postdata = "";
req.on('data', function(postdataChunk){
    postdata += postdataChunk;
});
zeah
quelle
1
Besser als dies postdata.split("&")zu tun wäre, das Kernmodul zu laden querystring = require('querystring')und dann Ihr postdatamit zu analysieren querystring.parse(postdata);
John Slegers
4

Ich konnte alle Parameter finden, indem ich den folgenden Code sowohl für POST- als auch für GET- Anforderungen verwendete.

var express = require('express');
var app = express();
const util = require('util');
app.post('/', function (req, res) {
    console.log("Got a POST request for the homepage");
    res.send(util.inspect(req.query,false,null));
})
ARUNBALAN NV
quelle
Stört es Sie, die Antwort mit Ihrer Express-Version zu aktualisieren?
lfender6445
3

Geschrieben in Express Version 4.16

Innerhalb der Router-Funktion können Sie mit der req.bodyEigenschaft auf die Post-Variable zugreifen. Wenn dies beispielsweise die POSTRoute Ihres Formulars wäre, würde es Ihre Eingaben zurücksenden:

function(req,res){
      res.send(req.body);

      //req.body.email would correspond with the HTML <input name="email"/>
}

PS für diejenigen, die mit PHP vertraut sind: Um auf die PHP- $_GETVariable zuzugreifen , verwenden wir req.queryund auf die PHP- $_POSTVariable, die wir req.bodyin Node.js verwenden.

Logan
quelle
1
var express        =         require("express");
var bodyParser     =         require("body-parser");
var app            =         express();

app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

app.get('/',function(req,res){
  res.sendfile("index.html");
});
app.post('/login',function(req,res){
  var user_name=req.body.user;
  var password=req.body.password;
  console.log("User name = "+user_name+", password is "+password);
  res.end("yes");
});
app.listen(3000,function(){
  console.log("Started on PORT 3000");
})
seme
quelle
1

Post-Parameter können wie folgt abgerufen werden:

app.post('/api/v1/test',Testfunction);
http.createServer(app).listen(port, function(){
    console.log("Express server listening on port " + port)
});

function Testfunction(request,response,next) {
   console.log(request.param("val1"));
   response.send('HI');
}
HamidKhan
quelle
1
Ist dir klar, dass das nicht funktioniert? paramwird für GET-Anfragen verwendet. Nicht für POST. In Ihrem Beispiel fehlen Details, was für Neuankömmlinge sehr verwirrend ist. Und obendrein request.paramist es tatsächlich veraltet, sodass Ihr Beispiel auf so vielen Ebenen falsch ist.
Vdegenne
0

Sie verwenden req.query.postmit falscher Methode req.query.postarbeitet mit method=get, method=postarbeitet mit Body-Parser .

Versuchen Sie dies einfach, indem Sie den Beitrag ändern , um Folgendes zu erhalten :

<form id="loginformA" action="userlogin" method="get">
<div>
    <label for="email">Email: </label>
    <input type="text" id="email" name="email"></input>
</div>
<input type="submit" value="Submit"></input>  
</form>

Und im Express-Code verwenden Sie 'app.get'

sagar saini
quelle
0

Verwenden Sie das Express-Fileupload- Paket:

var app = require('express')();
var http = require('http').Server(app);
const fileUpload = require('express-fileupload')

app.use(fileUpload());

app.post('/', function(req, res) {
  var email = req.body.email;
  res.send('<h1>Email :</h1> '+email);
});

http.listen(3000, function(){
  console.log('Running Port:3000');
});
Chirag
quelle