req.body leer auf Beiträge

256

Plötzlich ist dies bei allen meinen Projekten passiert.

Immer wenn ich mit node und body-parser einen Beitrag in nodejs mache, req.bodyist das ein leeres Objekt.

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

var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded())

// parse application/json
app.use(bodyParser.json())

app.listen(2000);

app.post("/", function (req, res) {
  console.log(req.body) // populated!
  res.send(200, req.body);
});

Über Ajax und Postbote ist es immer leer.

Jedoch über Curl

$ curl -H "Content-Type: application/json" -d '{"username":"xyz","password":"xyz"}' http://localhost:2000/

es funktioniert wie vorgesehen.

Ich habe versucht, Content-type : application/jsondie erstere manuell einzustellen, aber ich bekomme dann immer400 bad request

Das hat mich verrückt gemacht.

Ich dachte, es wäre etwas, das im Body-Parser aktualisiert wurde, aber ich habe ein Downgrade durchgeführt und es hat nicht geholfen.

Jede Hilfe dankbar, danke.

Joseph Dailey
quelle
16
Sie haben also versucht, den Content-TypePostboten explizit einzustellen? Wenn nicht, können Sie das versuchen, da ich zuvor Probleme mit dem Postboten hatte, der keine gesendet hat Content-Type.
mscdex
Ja, habe ich. Dann erhielt ich 400: ungültiger Json
Joseph Dailey
@mscdex - danke, ich habe nicht Content-Tupe in Postman gesetzt und wurde verrückt :)
Muzafar Ali
Für diejenigen, die hierher kommen, weil sie Dateien von ihren APIs senden / hochladen möchten und daher Formulardaten verwenden müssen. Sie benötigen etwas, um mit den Formulardaten umgehen zu können: npmjs.com/package/multer ist ein sehr beliebtes Paket.
Bhaskar
Egal was passiert, Postbote geht nicht sehr gut mit ganzen Zahlen und Float-Werten um. Wenn Sie Ganzzahl- oder Gleitkommawerte haben, stellen Sie sicher, dass Sie alles, sowohl Schlüssel als auch Werte, doppelt in Anführungszeichen setzen
anabeto93

Antworten:

272

Wählen Sie im Postboten der 3 verfügbaren Optionen für den Inhaltstyp "X-www-form-urlencoded" aus und es sollte funktionieren.

Auch um Fehlermeldung loszuwerden ersetzen:

app.use(bodyParser.urlencoded())

Mit:

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

Siehe https://github.com/expressjs/body-parser

Die Middleware "Body-Parser" verarbeitet nur JSON- und urlencodierte Daten, keine mehrteiligen

Mick Cullen
quelle
Das hat bei Postboten funktioniert, ich bin mir nicht sicher, warum es mit Ajax funktioniert, da ich nichts geändert habe.
Joseph Dailey
Aus irgendeinem Grund mussten http-Posts über Angular nicht URL-codiert sein, Ajax-Aufrufe jedoch. Weiß jemand warum?
youngrrrr
Das hat bei mir funktioniert, warum funktionierte es nicht mit Raw-Codierung?
Daniel Kobe
9
Jetzt ist Body-Parser mit Express.js nur verwendenapp.use(express.json());
Sujeet Agrahari
Ich danke dir sehr! Trotz der langen Zeit, in der dies beantwortet wurde, ist es immer noch relevant.
Spray'n'Pray
218

Um mit Postman HTTP-Postaktionen mit einer JSON-Rohdaten-Nutzlast zu testen, wählen Sie die rawOption aus und legen Sie die folgenden Header-Parameter fest:

Content-Type: application/json

Stellen Sie außerdem sicher, dass alle Zeichenfolgen, die als Schlüssel / Werte in Ihrer JSON-Nutzlast verwendet werden, in doppelte Anführungszeichen gesetzt werden.

Das body-parserPaket analysiert mehrzeilige JSON-Raw-Payloads einwandfrei.

{
    "foo": "bar"
}

Getestet in Chrome v37 und v41 mit der Erweiterung Postman v0.8.4.13 ( body-parserv1.12.2 und expressv4.12.3) mit dem folgenden Setup:

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

// configure the app to use bodyParser()
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// ... Your routes and methods here

Postbote rohe json Nutzlast

sirthud
quelle
Oh Mann, wie habe ich vermisst, dass ich ein JS-Objektliteral eingefügt habe, anstatt ein richtig formatiertes JSON-Objekt ...: -S ... danke Freund!
Wes Johnson
Umschließen von Zeichenfolgen, die als Schlüssel / Werte verwendet werden, in doppelte Anführungszeichen ... Leicht zu übersehen, aber ansonsten ein totaler Deal Breaker! Danke dir.
Loxyboi
Gute Verwendung von Screenshots.
Xan-Kun Clark-Davis
Bei Verwendung form-datain Postman zum Posten der Daten erhalte ich immer die {}in der req.body. Soll ich die Content-TypeOption einstellen ?
Mingchau
56

Ich habe einen wirklich dummen Fehler gemacht und vergessen, nameAttribute für Eingaben in meiner HTML-Datei zu definieren .

Also statt

<input type="password" class="form-control" id="password">

Ich habe das.

<input type="password" class="form-control" id="password" name="password">

Jetzt request.bodyist wie folgt bevölkert:{ password: 'hhiiii' }

Jason Kim
quelle
1
Bam. Das war das Problem. Vielen Dank!
Matt West
Das war genau mein Problem, eine Formulareingabe ohne Namenswerte, die stundenlang versucht hat, es herauszufinden. Vielen Dank.
Karensantana
37

Ich habe festgestellt, dass es beim Senden mit Inhaltstyp funktioniert

"application / json"

in Kombination mit serverseitig

app.use(bodyParser.json());

Jetzt kann ich über senden

var data = {name:"John"}
var xmlHttp = new XMLHttpRequest();
xmlHttp.open("POST", theUrl, false); // false for synchronous request
xmlHttp.setRequestHeader("Content-type", "application/json");
xmlHttp.send(data);

und das Ergebnis ist request.body.nameauf dem Server verfügbar .

Xan-Kun Clark-Davis
quelle
Danke für die positive Abstimmung. Ich denke wirklich, dass dies die sauberste, wenn auch nicht die einfachste Lösung ist, da Sie sowieso den richtigen Inhaltstyp senden sollten. Meiner Ansicht nach.
Xan-Kun Clark-Davis
das ist die Antwort!
Gel
In meinem Fall musste ich es ändernxmlHttp.send(JSON.stringify(data));
endo64
18

Ich bin heute auf dieses Problem gestoßen, und was behoben wurde, war das Entfernen des inhaltlichen Headers in Postman! Sehr eigenartig. Fügen Sie es hier hinzu, falls es jemandem hilft.

Ich habe das BeerLocker-Tutorial hier verfolgt: http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/

Stein
quelle
2
Ich hatte das gleiche Problem. Es war nicht genug, den Header "deaktiviert" (und ausgegraut) zu haben, ich musste ihn vollständig entfernen. Obwohl die Quellschaltfläche "</>" anzeigt, dass ich diesen Header nicht gesendet habe, während sich der Inhaltstyp im deaktivierten Zustand befindet, musste er dennoch vollständig entfernt werden.
TheRemix
Ich kann nicht herausfinden, wie die Standardheader in der Postman Chrome-Erweiterung entfernt werden. Verwenden Sie die App möglicherweise?
WestleyArgentum
Oh, ich habe die App installiert und sie funktioniert viel besser als die Erweiterung. Entschuldigung für den Lärm.
WestleyArgentum
12

Sie müssen überprüfen, ob die Body-Parser-Middleware richtig auf den Anforderungstyp (json, urlencoded) eingestellt ist.

Wenn Sie eingestellt haben,

app.use(bodyParser.json());

dann müssen Sie im Postboten die Daten als roh senden.

https://i.stack.imgur.com/k9IdQ.png Postboten-Screenshot

Wenn Sie eingestellt haben,

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

dann sollte die Option 'x-www-form-urlencoded' ausgewählt werden.

Tuan
quelle
Was ist mit beiden? (bodyParser.urlencoded und bodyParser.json ()) ... welches kann ich beim Postboten verwenden?
TommyLeong
9

Mein Problem war, dass ich zuerst die Route erstellt habe

// ...
router.get('/post/data', myController.postHandler);
// ...

und Registrieren der Middleware nach der Route

app.use(bodyParser.json());
//etc

aufgrund der App-Struktur & Kopieren und Einfügen des Projekts aus Beispielen.

Nachdem ich die Reihenfolge für die Registrierung der Middleware vor der Route festgelegt hatte, funktionierte alles.

Fiat
quelle
danke fiat, mit der richtigen bestellung und mit dem rohen tab hat es endlich für mich funktioniert
Alex
4

Selbst als ich node.js zum ersten Mal lernte, als ich anfing, es über eine Web-App zu lernen, hatte ich all diese Dinge in meiner Form gut gemacht, aber ich konnte keine Werte in der Post-Anfrage erhalten. Nach langem Debuggen wurde mir klar, dass ich in der von mir bereitgestellten Form enctype="multipart/form-data"keine Werte erhalten konnte. Ich habe es einfach entfernt und es hat bei mir funktioniert.

Shaggie
quelle
Ja, dies funktionierte auch, um den Formularkörper zu erhalten , verursachte dann aber ein weiteres Problem mit meinem Formular - im Grunde konnte die Datei nicht hochgeladen werden, wie dies erforderlich istenctype="multipart/form-data"
Tsando
Übrigens, nur um meinen obigen Kommentar zu ergänzen, ich habe es geschafft, dies multerzum Laufen
tsando
3

Wenn Sie keinen encType verwenden (Standard ist application/x-www-form-urlencoded), erhalten Sie zwar Texteingabefelder, aber keine Datei.

Wenn Sie ein Formular haben, in dem Sie Texteingaben und Dateien veröffentlichen möchten, verwenden Sie den multipart/form-dataCodierungstyp und zusätzlich multerMiddleware. Multer analysiert das Anforderungsobjekt und bereitet sich req.fileauf Sie vor. Alle anderen Eingabefelder sind über verfügbar req.body.

Mohammad Haque
quelle
1
danke - multerwar in der Tat die Lösung für mein Problem. Es wäre gut, wenn Sie ein Beispiel hinzufügen könnten, wie Sie dies als Teil Ihrer Antwort verwenden können
tsando
2

Ein ähnliches Problem ist mir passiert, ich habe einfach die Reihenfolge der Rückrufparameter gemischt. Stellen Sie sicher, dass Sie die Rückruffunktionen in der richtigen Reihenfolge einrichten. Zumindest für alle, die das gleiche Problem haben.

router.post('/', function(req, res){});
Henry Ollarves
quelle
2

Stellen Sie sicher, dass ["key": "type", "value": "json"] & ["key": "Content-Type", "value": "application / x-www-form-urlencoded"] in Ihrem enthalten ist Postbotenanforderungsheader

vpage
quelle
2

Ich habe dieses Problem multerwie oben vorgeschlagen gelöst , aber sie haben es versäumt, ein ausführliches Beispiel dafür zu geben. Grundsätzlich kann dies passieren, wenn Sie eine Formulargruppe mit haben enctype="multipart/form-data". Hier ist der HTML-Code für das Formular, das ich hatte:

<form action="/stats" enctype="multipart/form-data" method="post">
  <div class="form-group">
    <input type="file" class="form-control-file" name="uploaded_file">
    <input type="text" class="form-control" placeholder="Number of speakers" name="nspeakers">
    <input type="submit" value="Get me the stats!" class="btn btn-default">            
  </div>
</form>

Und hier erfahren Sie, wie multerSie die Werte und Namen dieses Formulars mit Express.jsund abrufen können node.js:

var multer  = require('multer')
var upload = multer({ dest: './public/data/uploads/' })
app.post('/stats', upload.single('uploaded_file'), function (req, res) {
   // req.file is the name of your file in the form above, here 'uploaded_file'
   // req.body will hold the text fields, if there were any 
   console.log(req.file, req.body)
});
Tsando
quelle
1

Ich hatte vor ein paar Minuten das gleiche Problem, ich habe alles Mögliche in den obigen Antworten versucht, aber jede davon hat funktioniert.

Das einzige, was ich getan habe, war das Upgrade der Node JS-Version. Ich wusste nicht, dass ein Upgrade Auswirkungen auf etwas haben könnte, aber es tat es.

Ich habe die Node JS-Version 10.15.0(neueste Version) installiert , bin zurückgekehrt 8.11.3und alles funktioniert jetzt. Vielleicht body-parsersollte das Modul dies beheben.

Phi
quelle
1

Ich hatte den Namen nicht in meiner Eingabe ... meine Anfrage war leer ... froh, dass das fertig ist und ich weiter codieren kann. Vielen Dank an alle!

Antwort, die ich von Jason Kim verwendet habe:

Also statt

<input type="password" class="form-control" id="password">

ich habe das

<input type="password" class="form-control" id="password" name="password">
Luke McCormick
quelle
1

Sie sollten dies nicht tun, JSON.stringify(data)während Sie wie unten beschrieben über AJAX senden.

Dies ist KEIN korrekter Code:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: JSON.stringify(data),
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}   

Der richtige Code lautet:

function callAjax(url, data) {
    $.ajax({
        url: url,
        type: "POST",
        data: data,
        success: function(d) {
            alert("successs "+ JSON.stringify(d));
        }
    });
}
Achilles Ram Nakirekanti
quelle
Eine wichtige Sache, die Sie hier beachten sollten, ist, dass Sie beim Schreiben sicherstellen müssen, dass Sie "POST" groß schreiben. Ich habe Fälle gesehen, in denen nur die Verwendung von "post" zu einem leeren req.body geführt hat.
Matt C.
1

Wenn Sie mit dem Postboten arbeiten, bestätigen Sie diese Informationen, wenn Sie eine API anfordern

Geben Sie hier die Bildbeschreibung ein

Vignesh
quelle
0

Ich habe restify anstelle von express verwendet und bin auf dasselbe Problem gestoßen. Die Lösung war zu tun:

server.use(restify.bodyParser());
Prabhat
quelle
0

Ich glaube, das kann sich lösen app.use(express.json());

Cleber Carvalho
quelle
0

Ändern Sie app.use(bodyParser.urlencoded());Ihren Code in

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

und im Postboten ändern Sie im Header den Content-TypeWert von application/x-www-form-urlencodedbisapplication/json

Ta :-)

Abhijith Brumal
quelle
0

Vielen Dank für Ihre tollen Antworten! Ich habe einige Zeit auf der Suche nach einer Lösung verbracht und auf meiner Seite einen elementaren Fehler gemacht: Ich habe bodyParser.json()innerhalb der Funktion aufgerufen:

app.use(['/password'], async (req, res, next) => {
  bodyParser.json()
  /.../
  next()
})

Ich musste es nur tun app.use(['/password'], bodyParser.json())und es funktionierte ...

musiquarc
quelle
0

Beim Postboten bekam ich, selbst nachdem ich der akzeptierten Antwort gefolgt war, einen leeren Anfragetext. Es stellte sich heraus, dass kein Header namens aufgerufen wurde

Content-Length : <calculated when request is sent>

Dieser Header war standardmäßig vorhanden (zusammen mit 5 anderen), die ich deaktiviert habe. Wenn Sie dies aktivieren, erhalten Sie den Anfragetext.

kaushalpranav
quelle
0

Mein Problem war, zuerst die Route zu erstellen. require("./routes/routes")(app); Ich habe sie vorher an das Ende des Codes verschoben app.listen und es hat funktioniert!

Tushar Kudal
quelle