Express.js req.body undefiniert

291

Ich habe dies als Konfiguration meines Express-Servers

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

Aber immer noch, wenn ich req.body.somethingauf meinen Routen danach frage, erhalte ich einen Fehler, der darauf hinweist body is undefined. Hier ist ein Beispiel für eine Route, die Folgendes verwendet req.body:

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

Ich habe gelesen, dass dieses Problem durch das Fehlen von verursacht wird, app.use(express.bodyParser());aber wie Sie sehen können, nenne ich es vor den Routen.

Irgendeine Ahnung?

Masiar
quelle

Antworten:

296

Sie müssen sicherstellen, dass Sie alle Konfigurationen definieren, bevor Sie Routen definieren. In diesem Fall können Sie die Verwendung fortsetzen express.bodyParser().

Ein Beispiel ist wie folgt:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});

app.listen(port);

app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});
Mark Bonano
quelle
9
Das hat bei mir funktioniert. Hinweis: Leider setzen einige Tutorials (wie ich) Routen vor app.configure (). In meinem Fall war dies in Form von app.get / post usw. und einem require () einschließlich dieser.
Bendman
1
Vielen Dank, ich habe den ganzen Tag dieses Problem behoben.
jfplataroti
11
ab Express 4 wird app.use (app.router) entfernt. Bitte lesen
Jonathan Ong
15
Ab Express 4 werden Middlewares wie bodyParser nicht mehr mit Express gebündelt und müssen separat installiert werden. Weitere Informationen finden Sie hier: github.com/senchalabs/connect#middleware .
andrea.rinaldi
2
Vielen Dank. Diese Antwort ist mehr als 2 Jahre alt und hilft immer noch Menschen in Schwierigkeiten :)
Lorenzo Marcon
275

Die neuesten Versionen von Express (4.x) haben die Middleware vom Kernframework entbündelt. Wenn Sie einen Body Parser benötigen, müssen Sie ihn separat installieren

npm install body-parser --save

und dann tun Sie dies in Ihrem Code

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())
Jay
quelle
2
Ich habe kürzlich aktualisiert, um 4.x auszudrücken. Anfangs, als ich versuchte, req.body zu protokollieren, zeigte es mir undefiniert. Sobald ich den Body-Parser installiert und verwendet habe, werden mir die erwarteten Werte für req.body angezeigt. :)
Alok Adhao
Ich fand dies nützlich, als ich herausfinden wollte, warum meine POST-Anfragen nicht mit json-server funktionierten.
Freethebees
Ich habe meinen Tag gerettet, insbesondere den Teil 'app.use (bodyParser.json ())'. Dank bro ! : D
neaGaze
Dies sollte die akzeptierte Antwort sein, da es für Express 4 völlig funktioniert! Danke mein Herr!
Kombinieren Sie den
2
app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json()) rettete mich !!
Pramesh Bajracharya
70

Nein, Sie müssen app.use(express.bodyParser())vorher verwenden app.use(app.router). In der Tat app.use(app.router)sollte das letzte sein, was Sie anrufen.

danmactough
quelle
Selbst app.use(app.router).use
wenn Sie
Ok, nach ein bisschen Mühe habe ich es mit app.use(require('connect').bodyParser());statt gelöst app.use(express.bodyParser());.
Masiar
Ja, die Antwort ist auch bei Verwendung wahr var router=express.Router().
Istiaque Ahmed
1
Leichter Nachtrag, sollten Sie nach dem app.router
craft
Segne diesen Kommentar
Ke Ke
40

Stellen Sie zunächst sicher, dass Sie das npm-Modul mit dem Namen 'body-parser' installiert haben, indem Sie Folgendes aufrufen:

npm install body-parser --save

Stellen Sie dann sicher, dass Sie die folgenden Zeilen eingefügt haben, bevor Sie Routen aufrufen

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

app.use(bodyParser.json());
Ankit kaushik
quelle
Wenn es express.json verwendet, warum dann Body-Parser importieren?
SanSolo
38

Express 4 verfügt über einen integrierten Body-Parser. Es ist nicht erforderlich, einen separaten Body-Parser zu installieren. Also unten wird funktionieren:

export const app = express();
app.use(express.json());
TechTurtle
quelle
37

Der Header "Content-Type in Request" ist sehr wichtig, insbesondere wenn Sie die Daten von Curl oder anderen Tools veröffentlichen.

Stellen Sie sicher, dass Sie etwas wie application / x-www-form-urlencoded, application / json oder andere verwenden. Dies hängt von Ihren Post-Daten ab. Lassen Sie dieses Feld leer, um Express zu verwirren.

Kevin Xue
quelle
12
+1 Das war das Problem für mich. Ich habe Postman for Chrome verwendet, um eine in REST integrierte JSON-API zu testen, aber das von Express empfangene Objekt war jedes Mal leer. Es stellt sich heraus, dass Postman standardmäßig nicht automatisch den Header 'Content-Type: application / json' hinzufügt, selbst wenn Sie raw> json auswählen.
Jordanien
@ Jordan +1 Danke, dass du darauf hingewiesen hast. Tatsächlich habe ich gerade meine Überschriften überprüft und sehe, dass sie immer noch auf "Text / Nur" eingestellt sind, obwohl ich "json" ausgewählt habe.
Ingenieur
Ugh ... 7 Jahre später und das ist es immer noch, was mich
auslöst
33

Wie bereits unter einem Kommentar gepostet, habe ich es mit gelöst

app.use(require('connect').bodyParser());

anstatt

app.use(express.bodyParser());

Ich weiß immer noch nicht, warum das Einfache express.bodyParser()nicht funktioniert ...

Masiar
quelle
1
@ Masiar Das funktioniert bei mir nicht. Ich benutze ExpressJS 4 und ich bekomme Fehler wie diesen. Fehler: Modul 'connect' kann nicht gefunden werden
Jeyarathnem Jeyachanthuru
1
@JeyTheva Mine ist eine ziemlich alte Lösung, daher haben sich die Dinge in der Zwischenzeit möglicherweise geändert. Ich schlage vor, Sie versuchen, das connectModul über zu installieren npm install connectund es erneut zu versuchen . Dies ist das einzige, woran ich denken kann, wenn ich die Ausgabe Ihres Fehlers lese.
Masiar
4
Hier ist die neueste Dokumentation zur Lösung dieses Problems: npmjs.com/package/body-parser Für andere, bei denen dieses Problem auftritt , "post express 4", hat es für mich funktioniert, den Content-TypeHeader auf zu setzen application/json.
Grant Eagon
3
Hier ist die neueste Dokumentation zur Lösung dieses Problems: npmjs.com/package/body-parser Nach der Installation von body- parser funktionierte dies immer noch nicht. Was funktionierte, war das Setzen des Content-TypeHeaders auf, application/jsonals ich meine Anfrage erledigte .
Grant Eagon
1
application/jsonvs text/jsonin der Anfrage funktioniert, wie von @GrantEagon vorgeschlagen.
Strider
21
// Require body-parser (to receive post data from clients)

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

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

// parse application/json

app.use(bodyParser.json())
ASHISH RANJAN
quelle
20

Fügen Sie in Ihrem app.js

vor dem Anruf des Routers

const app = express();
app.use(express.json());
Abdesselam
quelle
2
Du hast meinen Tag gerettet, Mann! Der Schlüssel ist das Hinzufügen der Leitung vor dem
Anrufrouter
Dieses Ding hat mich gerettet. Danke :)
Farrukh Faizy
12

Der Body-Parser wird anscheinend nicht mehr mit Express ausgeliefert. Möglicherweise müssen wir es separat installieren.

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

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

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

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

Weitere Informationen und Beispiele finden Sie auf der Git-Seite https://github.com/expressjs/body-parser .

Praneesh
quelle
1
Dies scheint das neue Express 4.x-Format zu sein und hat für mich funktioniert. Der in anderen Antworten erwähnte express.bodyParser () funktioniert in 4.x nicht.
DustinB
10

Für den Fall, dass jemand auf dasselbe Problem stößt, das ich hatte; Ich verwende ein URL-Präfix wie

http://example.com/api/

welches mit Router eingerichtet wurde

app.use('/api', router); 

und dann hatte ich folgendes

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

Was mein Problem behoben hat, war das Platzieren der Bodyparser-Konfiguration oben app.use('/api', router);

Finale

// setup bodyparser
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

//this is a fix for the prefix of example.com/api/ so we dont need to code the prefix in every route
    app.use('/api', router); 
Jeff Beagley
quelle
9

express.bodyParser () muss mitgeteilt werden, um welche Art von Inhalt es sich handelt. Daher müssen Sie sicherstellen, dass Sie beim Ausführen einer POST-Anforderung den Header "Content-Type" einschließen. Andernfalls weiß bodyParser möglicherweise nicht, was mit dem Text Ihrer POST-Anforderung zu tun ist.

Wenn Sie curl verwenden, um eine POST-Anforderung auszuführen, die ein JSON-Objekt im Hauptteil enthält, sieht dies ungefähr so ​​aus:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

Wenn Sie eine andere Methode verwenden, stellen Sie sicher, dass Sie dieses Headerfeld mit der entsprechenden Konvention festlegen.

ab107
quelle
8

Verwenden Sie app.use (bodyparser.json ()); vor dem Routing. //. app.use ("/ api", Routen);

user1614168
quelle
7

Sie können versuchen, diese Codezeile oben hinzuzufügen (nach Ihren erforderlichen Anweisungen):

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

Informationen zu den Gründen für die Funktionsweise finden Sie in den Dokumenten: https://www.npmjs.com/package/body-parser#bodyparserurlencodedoptions

Anthony Cantellano
quelle
Ich meine, deine Antwort ist richtig, aber sie unterscheidet sich nicht von den anderen.
Dwjohnston
7

Meistens ist req.body aufgrund des fehlenden JSON-Parsers undefiniert

const express = require('express');
app.use(express.json());

könnte für den Body-Parser fehlen

const bodyParser  = require('body-parser');
app.use(bodyParser.urlencoded({extended: true}));

und manchmal ist es aufgrund des Cros-Ursprungs undefiniert, also füge sie hinzu

const cors = require('cors');
app.use(cors())
König Neo
quelle
5

Das ist mir heute passiert. Keine der oben genannten Lösungen funktioniert für mich. Aber ein bisschen googeln hat mir geholfen, dieses Problem zu lösen. Ich codiere für Wechat-Server von Drittanbietern.

Etwas komplizierter wird es, wenn für Ihre Anwendung node.js Streaming-POST-Daten gelesen werden müssen, z. B. eine Anforderung von einem REST-Client. In diesem Fall wird die Eigenschaft "lesbar" der Anforderung auf "true" gesetzt und die POST-Daten müssen in Blöcken gelesen werden, um den gesamten Inhalt zu erfassen.

http://www.primaryobjects.com/CMS/Article144

Spikeyang
quelle
In dem Beitrag wird die Übermittlung von HTML-Formularen als von der REST-Client-Anforderung verschieden erwähnt. sind nicht beide http Anfrage? POST ist also der einzige Fall, der Streaming erfordert?
10.
5

Viel Zeit verschwendet:

Abhängig vom Inhaltstyp in Ihrer Client- Anfrage sollte
der Server eine andere haben, eine der folgenden app.use ():

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

Quelle: https://www.npmjs.com/package/body-parser#bodyparsertextoptions

Beispiel:

Auf der Client-Seite hatte ich unter der Überschrift:

Content-Type: "text/xml"

Auf der Serverseite habe ich also Folgendes verwendet:

app.use(bodyParser.text({type: 'text/xml'}));

Dann hat req.body gut funktioniert.

Manohar Reddy Poreddy
quelle
5

In Express 4 ist das ganz einfach

const app = express()
const p = process.env.PORT || 8082

app.use(express.json()) 
Gerardo Bautista
quelle
4

Um zu arbeiten, müssen Sie app.use (app.router) nach app.use (express.bodyParser ()) wie folgt ausführen :

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);
HenioJR
quelle
1
Ihr Kommentar und Ihr Code-Snippet sind widersprüchlich. Zuerst sagen , Sie verwenden müssen app.useauf app.routervor , express.bodyParseraber Ihr Code zeigt deutlich , Es ist nach. Also was ist es?
Levi Roberts
1
Tut mir leid, Mann. Sie müssen app.router nach express.bodyParser verwenden.
HenioJR
1
Vielen Dank, dass Sie @LeviRoberts
HenioJR
4
var bodyParser = require('body-parser');
app.use(bodyParser.json());

Das hat mir den Tag gerettet.

isdot
quelle
4

Dieses Problem kann daran liegen, dass Sie keinen Body-Parser verwendet haben ( Link )

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

var app = express();
app.use(bodyParser.json());
Arindam
quelle
3

Ich habe es gelöst mit:

app.post('/', bodyParser.json(), (req, res) => {//we have req.body JSON
});
Kkkk Kkkk
quelle
3

Dies ist auch eine Möglichkeit : Stellen Sie sicher, dass Sie diesen Code vor der Route in Ihre Datei app.js (oder index.js) schreiben.

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
Inamur Rahman
quelle
2

Sie können den Express-Body-Parser verwenden.

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
Kuldeep Mishra
quelle
2

In der neuesten Version von Express ist bereits ein Body-Parser integriert. So können Sie verwenden:

const express = require('express);
... 
app.use(express.urlencoded({ extended: false }))
.use(express.json());
LEMUEL ADANE
quelle
1

Wenn Sie eine SOAP-Nachricht veröffentlichen, müssen Sie den Raw-Body-Parser verwenden:

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

app.use(bodyParser.raw({ type: 'text/xml' }));
opewix
quelle
1

Aufbauend auf @ kevin-xue muss der Inhaltstyp deklariert werden. In meinem Fall trat dies nur bei IE9 auf, da XDomainRequest keinen Inhaltstyp festlegt, sodass bodyparser und expressjs den Hauptteil der Anforderung ignorierten.

Ich habe dies umgangen, indem ich den Inhaltstyp explizit festgelegt habe, bevor ich die Anforderung an den Body-Parser weitergeleitet habe:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());
purpletonisch
quelle
1

Dank an @spikeyang für die großartige Antwort ( siehe unten). Nachdem ich den vorgeschlagenen Artikel gelesen hatte, der dem Beitrag beigefügt war, beschloss ich, meine Lösung zu teilen.

Wann verwenden?

Für die Lösung mussten Sie den Express-Router verwenden, um ihn genießen zu können. Wenn Sie also versucht haben, die akzeptierte Antwort ohne Erfolg zu verwenden, verwenden Sie einfach diese Funktion zum Kopieren und Einfügen:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

    req.on('data', function (data) 
    {
        body += data; 
    });

    req.on('end', function () 
    {
        ready(body);
    });
}

und nenne es wie:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

HINWEIS: Für große Nutzdaten verwenden Sie bitte einen Array-Puffer ( mehr @ MDN ).

ymz
quelle
Das bodyParser-Paket wird häufig verwendet und übersetzt die Nutzdaten in ein Body-Objekt. wie in anderen Antworten angegeben
Schuere
1

Wenn Sie ein externes Tool verwenden, um die Anforderung zu stellen, müssen Sie den Header hinzufügen:

Content-Type: application/json

Inc33
quelle
Dieser hat mir geholfen, ich habe mit Postman gearbeitet, danke Kumpel.
R. Gurung
1

Für jeden, für den keine der oben genannten Antworten funktioniert hat, musste ich Cors zwischen Front-End und Express aktivieren.

Sie können dies entweder tun durch:

  1. Herunterladen und Aktivieren einer CORS-Erweiterung für Ihren Browser, z.

    https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=de

    für Chrome

oder von

  1. Zeilen hinzufügen

    var cors=require('cors');
    
    app.use(cors());

zu Ihrer Express- app.jsSeite. (Nachher npm install cors)

lmb
quelle