Come accedere al corpo della richiesta durante il POST utilizzando Node.js ed Express?


175

Ho il seguente codice Node.js:

var express = require('express');
var app = express.createServer(express.logger());
app.use(express.bodyParser());

app.post('/', function(request, response) {
    response.write(request.body.user);
    response.end();
});

Ora se POSSO qualcosa del tipo:

curl -d user=Someone -H Accept:application/json --url http://localhost:5000

Ottengo Someonecome previsto. Ora, cosa succede se desidero ottenere il corpo della richiesta completo? Ho provato a farlo response.write(request.body)ma Node.js genera un'eccezione che dice "il primo argomento deve essere una stringa o un buffer ", quindi passa a un "ciclo infinito" con un'eccezione che dice " Impossibile impostare le intestazioni dopo che sono state inviate "; questo vale anche se l'ho fatto var reqBody = request.body;e poi scrivendo response.write(reqBody).

Qual è il problema qui?

Inoltre, posso ottenere la richiesta non elaborata senza utilizzarla express.bodyParser()?


Sembra che ci sia qualcosa con response.write(reqBody); quando uso le response.send(reqBody)cose funzionano bene ... e sì, lo uso response.enddopo response.write.
TheBlueSky

Risposte:


161

Express 4.0 e versioni successive:

$ npm install --save body-parser

E poi nella tua app nodo:

const bodyParser = require('body-parser');
app.use(bodyParser);

Express 3.0 e versioni precedenti:

Prova a passare questo nella tua chiamata cURL:

--header "Content-Type: application/json"

e assicurandoti che i tuoi dati siano in formato JSON:

{"user":"someone"}

Inoltre, è possibile utilizzare console.dir nel codice node.js per visualizzare i dati all'interno dell'oggetto come nell'esempio seguente:

var express = require('express');
var app = express.createServer();

app.use(express.bodyParser());

app.post('/', function(req, res){
    console.dir(req.body);
    res.send("test");
}); 

app.listen(3000);

Quest'altra domanda potrebbe anche aiutare: come ricevere JSON nella richiesta POST express node.js?

Se non desideri utilizzare bodyParser, consulta questa altra domanda: https://stackoverflow.com/a/9920700/446681


Ho provato a utilizzare curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000ma mi stava dando l'errore " Token inatteso u ", ecco perché sono passato alla chiamata menzionata nel mio post originale.
TheBlueSky

Sto marcatura questo come risposta a causa del collegamento stackoverflow.com/a/9920700/446681
TheBlueSky

40
express.bodyParser()è obsoleto in Express 4.x. Utilizzare invece npmjs.org/package/body-parser .
Luc,

@TheBlueSky il motivo per cui hai ottenuto "Token inatteso u" è stato perché la shell ha consumato le doppie virgolette. La stessa cosa succede se lo fai echo any"thing". I dati che stai postando dovrebbero essere tra virgolette per evitare che ciò accada.
Tom Fenech,

11
Da express 4.16.0 o versioni successive è possibile utilizzare express.json () in app.use () in questo modo => app.use (express.json ());
Mitro,

187

A partire da Express v4.16 non è necessario alcun modulo aggiuntivo, basta usare il middleware JSON integrato :

app.use(express.json())

Come questo:

const express = require('express')

app.use(express.json())    // <==== parse request body as JSON

app.listen(8080)

app.post('/test', (req, res) => {
  res.json({requestBody: req.body})  // <==== req.body will be a parsed JSON object
})

Nota - body-parser, da cui dipende, è già incluso in express.

Inoltre, non dimenticare di inviare l'intestazione Content-Type: application/json


14
Grazie, questa è la risposta migliore per 4.16+ allora. Nessun'altra dipendenza e funziona come un fascino!
codepleb,

1
La migliore / unica soluzione che ho trovato che non ha bisogno del body-parser
Mote Zart,

41

A partire da Express 4, il seguente codice sembra fare il trucco. Nota che dovrai installare body-parserusando npm.

var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));


app.listen(8888);

app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});

29
Per l'analisi dei corpi json è necessario aggiungere la seguente rigaapp.use(bodyParser.json())
Camilo Silva,

1
@ cml.co c'è qualche motivo app.use(bodyParser.urlencoded({ extended: true })è richiesto anche ? Sto pubblicando un documento piuttosto complesso come JSON nella richiesta e extended: falsenon ha funzionato. Solo quando l'ho impostato su true, la richiesta viene analizzata correttamente.
Utente Web

3
Solo una nota. Ho dovuto usare app.use(bodyParser.urlencoded({ extended: true }));AND app.use(bodyParser.json())per ottenere dati json su una configurazione del server AWS Linux con NodeJS ed Express.
David,

24
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json())

var port = 9000;

app.post('/post/data', function(req, res) {
    console.log('receiving data...');
    console.log('body is ',req.body);
    res.send(req.body);
});

// start the server
app.listen(port);
console.log('Server started! At http://localhost:' + port);

Questo ti aiuterà. Presumo che tu stia inviando un corpo in json.


Ho sempre dimenticato di aggiungere bodyParser.json () bit x_x grazie!
Jonny Asmar,

14

Per il 2019, non è necessario installare body-parser.

Puoi usare:

var express = require('express');
var app = express();
app.use(express.json())
app.use(express.urlencoded({extended: true}))
app.listen(8888);
app.post('/update', function(req, res) {
    console.log(req.body); // the posted data
});

8

Ciò può essere ottenuto senza body-parserla dipendenza così, ascoltare request:datae request:ende restituire la risposta sulla fine della richiesta, fare riferimento al di sotto di codice. rif: https://nodejs.org/en/docs/guides/anatomy-of-an-http-transaction/#request-body

var express = require('express');
var app = express.createServer(express.logger());

app.post('/', function(request, response) {

    // push the data to body
    var body = [];
    request.on('data', (chunk) => {
      body.push(chunk);
    }).on('end', () => {
      // on end of data, perform necessary action
      body = Buffer.concat(body).toString();
      response.write(request.body.user);
      response.end();
    });
});

3

Prova questo:

response.write(JSON.stringify(request.body));

Ciò prenderà l'oggetto bodyParsercreato per te e lo trasformerà nuovamente in una stringa e lo scriverà nella risposta. Se si desidera il corpo esatto della richiesta (con lo stesso spazio bianco, ecc.), Sarà necessario datae gli endascoltatori collegati alla richiesta prima e costruire il blocco di stringa per blocco come si può vedere nel codice sorgente di analisi json da connect .


1

Quello che affermi di aver "provato a fare" è esattamente quello che hai scritto nel codice che funziona "come previsto" quando lo invochi con il ricciolo.

L'errore che ricevi non sembra essere correlato a nessuno dei codici che ci hai mostrato.

Se si desidera ottenere la richiesta di materie prime, i gestori di impostare requestper le datae endeventi (e, naturalmente, rimuovere qualsiasi invocazioni express.bodyParser()). Si noti che gli dataeventi si verificheranno in blocchi e che, a meno che non si imposti una codifica per l' dataevento, tali blocchi saranno buffer, non stringhe.


quello era un errore di copia e incolla; Intendevo request.bodye no request.body.user, e l'ho corretto ora. A proposito, var reqBody = request.body;era ed è ancora corretto e quando lo provi otterrai l'errore che sto ricevendo. Ad ogni modo, puoi fare un esempio sull'impostazione del gestore request; Non mi sembra di trovarlo nella guida espressa.
TheBlueSky

1

Se sei abbastanza pigro da leggere blocchi di dati di post. potresti semplicemente incollare sotto le righe per leggere json.

Di seguito è riportato per TypeScript simile può essere fatto anche per JS.

app.ts

 import bodyParser from "body-parser";
 // support application/json type post data
 this.app.use(bodyParser.json());
 // support application/x-www-form-urlencoded post data
 this.app.use(bodyParser.urlencoded({ extended: false }));

In uno dei controller che ricevono la chiamata POST, utilizzare come mostrato di seguito

userController.ts

 public async POSTUser(_req: Request, _res: Response) {
   try {
          const onRecord = <UserModel>_req.body;
           /* Your business logic */
           _res.status(201).send("User Created");
        }
    else{
           _res.status(500).send("Server error");
           }        
   };

_req.body dovrebbe analizzare i tuoi dati json nel tuo modello TS.


1
Non sono sicuro se stai cercando di incoraggiare o scoraggiare le persone a usare la tua risposta chiamandole pigre :)
TheBlueSky

1

Sono assolutamente nuovo per JS ed ES, ma ciò che sembra funzionare per me è proprio questo:

JSON.stringify(req.body)

Fammi sapere se c'è qualcosa che non va!


esattamente quello di cui avevo bisogno
Josef Henn, il

0

Installa Body Parser con il comando seguente

$ npm install --save body-parser

Configura Body Parser

const bodyParser = require('body-parser');
app.use(bodyParser);
app.use(bodyParser.json()); //Make sure u have added this line
app.use(bodyParser.urlencoded({ extended: false }));

-3

Si utilizza il seguente codice per registrare i dati dei post:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});

2
La risposta data è incompleta senza includere il modulo body-parser.
gramcha,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.