Como acessar o corpo da solicitação no POST usando Node.js e Express?

174

Eu tenho o seguinte código 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();
});

Agora, se eu POST algo como:

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

Eu fico Someonecomo o esperado. Agora, e se eu quiser obter o corpo completo da solicitação? Eu tentei fazer, response.write(request.body)mas o Node.js lança uma exceção dizendo "o primeiro argumento deve ser uma string ou um buffer " e depois passa para um "loop infinito", com uma exceção que diz " Não é possível definir cabeçalhos após o envio. "; isso também é verdade mesmo que eu fiz var reqBody = request.body;e depois escrevi response.write(reqBody).

Qual é o problema aqui?

Além disso, posso obter a solicitação bruta sem usar express.bodyParser()?

O céu azul
fonte
Parece que há algo com response.write(reqBody); quando uso as response.send(reqBody)coisas estão funcionando bem ... e sim, uso response.enddepois response.write.
TheBlueSky

Respostas:

161

Express 4.0 e superior:

$ npm install --save body-parser

E então no seu aplicativo de nó:

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

Express 3.0 e abaixo:

Tente passar isso na sua chamada cURL:

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

e verifique se seus dados estão no formato JSON:

{"user":"someone"}

Além disso, você pode usar console.dir no código node.js para ver os dados dentro do objeto, como no exemplo a seguir:

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

Essa outra pergunta também pode ajudar: Como receber JSON na solicitação expressa do node.js POST?

Se você não quiser usar o bodyParser, verifique esta outra pergunta: https://stackoverflow.com/a/9920700/446681

Hector Correa
fonte
Eu tentei usar, curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000mas estava me dando o erro " Token inesperado u ", por isso mudei para a chamada mencionada na minha postagem original.
TheBlueSky
Estou marcando este como resposta devido à ligação stackoverflow.com/a/9920700/446681
TheBlueSky
40
express.bodyParser()foi descontinuado no Express 4.x. Use npmjs.org/package/body-parser .
Luc
@TheBlueSky, a razão pela qual você recebeu o "token inesperado u" foi porque o shell consumiu suas aspas duplas. A mesma coisa acontece se você fizer echo any"thing". Os dados que você está postando devem estar entre aspas para impedir que isso aconteça.
precisa
11
A partir do express 4.16.0 ou superior, é possível usar express.json () em app.use () desta maneira => app.use (express.json ());
Mitro 27/03
187

A partir do express v4.16, não há necessidade de módulos adicionais, basta usar o middleware JSON integrado :

app.use(express.json())

Como isso:

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 qual isso depende, está incluído no express.

Também não se esqueça de enviar o cabeçalho Content-Type: application/json

rustyx
fonte
14
Obrigado, esta é a melhor resposta para 4.16+ então. Sem outras dependências e funciona como um encanto!
codepleb
1
A melhor única solução / eu poderia achar que não precisa do corpo-parser
Mote Zart
41

No Express 4, o código a seguir parece fazer o truque. Observe que você precisará instalar 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
});
Walter Roman
fonte
29
Para analisar corpos JSON é exigido para adicionar a seguinte linhaapp.use(bodyParser.json())
Camilo Silva
1
@ cml.co há alguma razão app.use(bodyParser.urlencoded({ extended: true })é também necessário? Estou postando um documento bastante complexo como JSON na solicitação e extended: falsenão funcionou. Somente quando eu defini-lo como verdadeiro, a solicitação é analisada corretamente.
Usuário da web
3
Apenas uma nota. Tinha que usar app.use(bodyParser.urlencoded({ extended: true }));AND app.use(bodyParser.json())para obter dados json em uma configuração de servidor da AWS Linux com NodeJS e 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);

Isso irá ajudá-lo. Presumo que você esteja enviando corpo em json.

Gautam
fonte
Eu sempre esqueço de adicionar o bodyParser.json () bit x_x obrigado!
9139 Jonny Asmar
14

Para 2019, você não precisa instalar body-parser.

Você pode usar:

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
});
Shivam Gupta
fonte
8

Isto pode ser conseguido sem body-parserdependência, bem como, ouvir request:datae request:ende retornar a resposta no final da requisição, referem-se a seguir exemplo de código. ref: 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();
    });
});
Manivannan
fonte
3

Tente o seguinte:

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

Isso pegará o objeto bodyParsercriado para você e o transformará novamente em uma sequência de caracteres e gravará na resposta. Se quiser que o corpo da solicitação exata (com o mesmo espaço em branco, etc), você vai precisar datae endouvintes anexado ao pedido antes e construir o pedaço de cordas de pedaço como você pode ver no código-fonte de análise JSON de conexão .

Peter Lyons
fonte
1

O que você afirma ter "tentado fazer" é exatamente o que você escreveu no código que funciona "como esperado" quando você o invoca com curl.

O erro que você está recebendo não parece estar relacionado a nenhum código que você nos mostrou.

Se você deseja obter o pedido cru, manipuladores em conjunto requestpara os datae endeventos (e, claro, remover qualquer invocações de express.bodyParser()). Observe que os dataeventos ocorrerão em partes, e que, a menos que você defina uma codificação para o dataevento, essas partes serão buffers, não cadeias.

ebohlman
fonte
isso foi um erro de copiar e colar; Eu quis dizer request.bodye não request.body.user, e eu o corrigi agora. A propósito, o var reqBody = request.body;foi e ainda está correto e, quando você tentar, receberá o erro que estou recebendo. De qualquer forma, você pode dar um exemplo sobre como ativar o manipulador request; Não parece encontrá-lo em guia expresso.
TheBlueSky
1

Se você tiver preguiça de ler blocos de dados de postagem. você pode simplesmente colar as linhas abaixo para ler json.

Abaixo está o TypeScript semelhante também pode ser feito para 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 }));

Em um dos controladores que recebe chamadas POST, use como mostrado abaixo

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 deve estar analisando seus dados json no seu modelo TS.

Shujaath Khan
fonte
1
Eu não tenho certeza se você está tentando encorajar ou desencorajar as pessoas a usar a sua resposta, chamando-os preguiçosos :)
TheBlueSky
1

Eu sou absolutamente novo em JS e ES, mas o que parece funcionar para mim é apenas isso:

JSON.stringify(req.body)

Deixe-me saber se há algo errado com isso!

balintn
fonte
exatamente o que eu precisava
Josef Henn
0

Instale o Analisador de Corpo pelo comando abaixo

$ npm install --save body-parser

Configurar analisador de corpo

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 }));
Arun Abimanyu
fonte
-3

Você usa o seguinte código para registrar dados da postagem:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});
Chandra Kumar
fonte
2
A resposta fornecida é incompleta sem incluir o módulo analisador de corpo.
gramcha