req.body vazio nas postagens


256

De repente, isso vem acontecendo em todos os meus projetos.

Sempre que eu faço uma postagem no nodejs usando express e body-parser, req.bodyé um objeto vazio.

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

Via ajax e carteiro, está sempre vazio.

No entanto, via curl

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

funciona como pretendido.

Tentei configurar manualmente Content-type : application/jsonno primeiro, mas sempre obtive400 bad request

Isso está me deixando louco.

Eu pensei que era algo atualizado no analisador de corpo, mas fiz o downgrade e não ajudou.

Qualquer ajuda apreciada, obrigado.


16
Então você tentou explicitamente definir o Content-Typecarteiro? Caso contrário, você pode tentar isso, pois já tive problemas antes com o carteiro não enviando um Content-Type.
Mscdex

sim eu fiz. que é quando eu recebi 400: JSON inválida
Joseph Dailey

@mscdex - graças eu não definir conteúdo de tupe no carteiro e estava ficando louco :)
Muzafar Ali

Para as pessoas que estão vindo para cá porque desejam enviar / fazer upload de arquivos de suas APIs e, portanto, precisam usar dados de formulário. Você precisa de algo para lidar com os dados do formulário: npmjs.com/package/multer é um pacote bastante popular.
precisa saber é

Não importa o que aconteça, o carteiro não lida com números inteiros e valores flutuantes muito bem. Se você tem valores inteiros ou flutuador, garantir a aspas duplas tudo, ambas as chaves e valores
anabeto93

Respostas:


272

No Postman, das 3 opções disponíveis para o tipo de conteúdo, selecione "X-www-form-urlencoded" e deve funcionar.

Também para se livrar da mensagem de erro, substitua:

app.use(bodyParser.urlencoded())

Com:

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

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

O middleware 'body-parser' manipula apenas JSON e dados codificados por url, não multipartes


Isso funcionou para o carteiro, não sei por que funciona com o ajax, pois não mudei nada.
Joseph Dailey

Por algum motivo, as postagens http via Angular não precisavam ser codificadas por URL, mas as chamadas ajax. Alguém sabe o porquê?
youngrrrr

Isso funcionou para mim, por que não estava trabalhando com codificação bruta?
Daniel Kobe

9
agora corpo-analisador é embutido com express.js apenas usarapp.use(express.json());
Sujeet Agrahari

Muito obrigado! Apesar do longo tempo em que isso foi respondido, ainda é relevante.
Spray'n'Pray

218

Com o Postman, para testar ações de postagem HTTP com uma carga de dados JSON bruta, selecione a rawopção e defina os seguintes parâmetros de cabeçalho:

Content-Type: application/json

Além disso, certifique-se de agrupar todas as cadeias usadas como chaves / valores em sua carga JSON entre aspas duplas.

O body-parserpacote analisará as cargas úteis JSON brutas de várias linhas.

{
    "foo": "bar"
}

Testado no Chrome v37 e v41 com a extensão Postman v0.8.4.13 ( body-parserv1.12.2 e expressv4.12.3) com a configuração abaixo:

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

Postman raw json payload


Oh cara, como eu senti falta de colar um objeto JS literal em vez de um objeto JSON formatado corretamente ...: -S ... obrigado, amigo!
27415 Wes Wes Johnson

Envolvendo todas as seqüências de caracteres usadas como chave / valores entre aspas duplas ... Fácil de perder, mas, de outra forma, um negócio total! Obrigado.
Loxyboi

Bom uso de capturas de tela.
Xan-Kun Clark-Davis

Quando uso form-datano Postman para postar os dados, eu sempre recebo {}o req.body. Devo definir a Content-Typeopção?
Mingchau

56

Cometi um erro muito idiota e esqueci de definir name atributos para entradas no meu arquivo html.

Então, ao invés de

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

Eu tenho isto.

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

Agora request.bodyé preenchido assim:{ password: 'hhiiii' }


1
Bam. Esse foi o problema. Obrigado!
Matt West

Esse era exatamente o meu problema, uma entrada de formulário sem valores de nome, passava horas tentando descobrir isso. Obrigado.
karensantana

37

Eu descobri que funciona ao enviar com o tipo de conteúdo

"application / json"

em combinação com o lado do servidor

app.use(bodyParser.json());

Agora eu posso enviar via

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

e o resultado está disponível no request.body.nameservidor.


Obrigado pelo voto positivo. Realmente acho que essa é a solução mais limpa, embora não a mais simples, pois você deve enviar o tipo de conteúdo correto de qualquer maneira. Eu acho que.
Xan-Kun Clark-Davis

esta é a resposta!
Gel

No meu caso, tive que mudar paraxmlHttp.send(JSON.stringify(data));
endo64 11/12/19

18

Encontrei esse problema hoje, e o que foi corrigido foi remover o cabeçalho do tipo de conteúdo no Postman! Muito estranho. Adicioná-lo aqui, caso ajude alguém.

Eu estava seguindo o tutorial do BeerLocker aqui: http://scottksmith.com/blog/2014/05/29/beer-locker-building-a-restful-api-with-node-passport/


2
Eu tive o mesmo problema. tendo o cabeçalho "desmarcado" (e acinzentado) não era suficiente, tive que removê-lo completamente. mesmo que o botão de origem "</>" mostre que eu não estava enviando esse cabeçalho com o Tipo de conteúdo no estado desmarcado, ele ainda precisava ser completamente removido.
theRemix

Não consigo descobrir como remover os cabeçalhos padrão na extensão chrome postman ... talvez você esteja usando o aplicativo?
WestleyArgentum

Ah, eu instalei o aplicativo e ele funciona muito melhor do que a extensão. Desculpe pelo barulho.
WestleyArgentum

12

Você deve verificar se o middleware body-parser está definido corretamente para o tipo de solicitação (json, codificado por url).

Se você configurou,

app.use(bodyParser.json());

então, no carteiro, você deve enviar os dados como não processados.

https://i.stack.imgur.com/k9IdQ.png captura de tela do carteiro

Se você configurou,

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

a opção 'x-www-form-urlencoded' deve ser selecionada.


que tal ter os dois? (bodyParser.urlencoded e bodyParser.json ()) ... qual deles posso usar no carteiro?
TommyLeong 11/03

9

Meu problema era que eu estava criando a rota primeiro

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

e registrando o middleware após a rota

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

devido à estrutura do aplicativo, copiar e colar o projeto a partir de exemplos.

Depois de corrigir o pedido de registro do middleware antes da rota, tudo funcionou.


graças fiat, com a ordem certa e usando a guia cru ele trabalhou para mim no passado
Alex

4

Mesmo quando eu estava aprendendo o node.js pela primeira vez em que comecei a aprendê-lo pelo aplicativo da web, eu estava fazendo tudo isso de maneira adequada no meu formulário, ainda não consegui receber valores em uma solicitação posterior. Após uma longa depuração, vim a saber que, no formulário que forneço enctype="multipart/form-data"devido ao qual não consegui obter valores. Eu simplesmente o removi e funcionou para mim.


sim, isso também trabalhou para obter o corpo forma , mas , em seguida, causou outro problema com a minha forma - basicamente o arquivo não pôde ser carregado, pois isso requerenctype="multipart/form-data"
tsando

btw, apenas para acrescentar ao meu comentário acima, eu consegui começar este trabalho com multer- ver documentação sobre npmjs.com/package/multer
tsando

3

Parece que se você não usar nenhum encType (o padrão é application/x-www-form-urlencoded), receberá campos de entrada de texto, mas não obterá o arquivo.

Se você possui um formulário no qual deseja postar entrada e arquivo de texto, use o multipart/form-datatipo de codificação e, além disso, use o multermiddleware. Multer analisará o objeto de solicitação e se preparará req.filepara você e todos os outros campos de entrada estarão disponíveis req.body.


1
obrigado - multerfoi realmente a solução para o meu problema. Seria bom se você pudesse adicionar um exemplo de como usar isso como parte de sua resposta
tsando

2

Um problema semelhante aconteceu comigo, simplesmente misturei a ordem dos parâmetros de retorno de chamada. Verifique se você está configurando as funções de retorno de chamada na ordem correta. Pelo menos para quem tem o mesmo problema.

router.post('/', function(req, res){});

2

Verifique se ["key": "type", "value": "json"] e ["key": "Content-Type", "value": "application / x-www-form-urlencoded"] estão no seu cabeçalhos de solicitação de carteiro


2

Resolvi isso usando multero sugerido acima, mas eles deixaram de dar um exemplo de trabalho completo sobre como fazer isso. Basicamente, isso pode acontecer quando você tem um grupo de formulários enctype="multipart/form-data". Aqui está o HTML para o formulário que eu tinha:

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

E aqui está como usar multerpara obter os valores e nomes deste formulário com Express.jse 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)
});

1

Eu tive o mesmo problema alguns minutos atrás, tentei todo o possível nas respostas acima, mas qualquer uma delas funcionou.

A única coisa que fiz foi atualizar a versão do Node JS, não sabia que a atualização poderia afetar alguma coisa, mas foi.

Instalei a versão JS do nó 10.15.0( versão mais recente), retornei 8.11.3e tudo está funcionando agora. Talvez o body-parsermódulo deva resolver isso.


1

Eu não tinha o nome na minha entrada ... meu pedido estava vazio ... feliz que tenha terminado e eu possa continuar codificando. Obrigado a todos!

Resposta que usei por Jason Kim:

Então, ao invés de

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

eu tenho isto

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

1

você não deve JSON.stringify(data)enviar o AJAX como abaixo.

Este não é o código correto:

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

O código correto é:

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

Uma coisa importante a ser observada aqui é que, no tipo, certifique-se de colocar "POST" em maiúscula. Já vi casos em que o simples uso de "post" levou ao req.body em branco.
Matt C.

1

Se você estiver trabalhando com o carteiro, confirme essas coisas ao solicitar a API

insira a descrição da imagem aqui


0

Eu estava usando restify em vez de express e encontrei o mesmo problema. A solução foi fazer:

server.use(restify.bodyParser());


0

Altere app.use(bodyParser.urlencoded());seu código para

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

e no carteiro, no cabeçalho, altere o Content-Typevalor de application/x-www-form-urlencodedparaapplication/json

Ta :-)


0

Obrigado a todos pelas ótimas respostas! Passei bastante tempo procurando uma solução e, do meu lado, estava cometendo um erro elementar: estava ligando bodyParser.json()de dentro da função:

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

Eu só precisava fazer app.use(['/password'], bodyParser.json())e funcionou ...


0

No carteiro, mesmo depois de seguir a resposta aceita, eu estava recebendo um corpo de solicitação vazio. O problema acabou por não passar um cabeçalho chamado

Content-Length : <calculated when request is sent>

Esse cabeçalho estava presente por padrão (junto com outros 5) que eu desabilitei. Habilite isso e você receberá o corpo da solicitação.


0

Meu problema foi criar a rota primeiro require("./routes/routes")(app); , mudei para o final do código antes app.listen e funcionou!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.