Jak uzyskać dostęp do treści żądania podczas POSTowania przy użyciu Node.js i Express?

175

Mam następujący kod 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();
});

Teraz jeśli OPUBLIKUJĘ coś takiego:

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

Dostaję się Someonezgodnie z oczekiwaniami. A co, jeśli chcę uzyskać pełną treść żądania? Próbowałem to zrobić, response.write(request.body)ale Node.js zgłasza wyjątek mówiąc, że „ pierwszy argument musi być łańcuchem lub buforem ”, a następnie przechodzi do „nieskończonej pętli” z wyjątkiem, który mówi: „ Nie można ustawić nagłówków po ich wysłaniu. ”; to również prawda, nawet gdybym to zrobił, var reqBody = request.body;a potem pisał response.write(reqBody).

O co tu chodzi?

Czy mogę po prostu otrzymać surowe żądanie bez używania express.bodyParser()?

Niebieskie niebo
źródło
Wydaje się, że jest coś z response.write(reqBody); kiedy używam, response.send(reqBody)rzeczy działają dobrze ... i tak, używam response.endpóźniej response.write.
TheBlueSky

Odpowiedzi:

161

Express 4.0 i nowsze:

$ npm install --save body-parser

A następnie w aplikacji node:

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

Express 3.0 i starsze:

Spróbuj przekazać to w swoim wywołaniu cURL:

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

i upewniając się, że Twoje dane są w formacie JSON:

{"user":"someone"}

Możesz również użyć console.dir w swoim kodzie node.js, aby zobaczyć dane wewnątrz obiektu, jak w poniższym przykładzie:

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

Pomocne może być również inne pytanie: Jak odebrać JSON w żądaniu POST Express node.js?

Jeśli nie chcesz korzystać z bodyParser, sprawdź to drugie pytanie: https://stackoverflow.com/a/9920700/446681

Hector Correa
źródło
Próbowałem użyć, curl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000ale dawało mi to błąd „ Nieoczekiwany token u ”, dlatego przełączyłem się na wspomniane połączenie w moim oryginalnym poście.
TheBlueSky
Oznaczam to jako odpowiedź ze względu na link stackoverflow.com/a/9920700/446681
TheBlueSky
40
express.bodyParser()jest przestarzałe w Express 4.x. Zamiast tego użyj npmjs.org/package/body-parser .
Luc
@TheBlueSky powodem, dla którego otrzymałeś „Nieoczekiwany token u”, był fakt, że powłoka zużyła Twoje podwójne cudzysłowy. To samo dzieje się, jeśli to zrobisz echo any"thing". Dane, które publikujesz, powinny znajdować się w cudzysłowie, aby temu zapobiec.
Tom Fenech
11
Od express 4.16.0 lub nowszych możliwe jest użycie express.json () w app.use () w ten sposób => app.use (express.json ());
Mitro
187

Począwszy od wersji Express v4.16 nie ma potrzeby stosowania żadnych dodatkowych modułów, wystarczy skorzystać z wbudowanego oprogramowania pośredniczącego JSON :

app.use(express.json())

Lubię to:

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

Uwaga - body-parserod czego to zależy, jest już zawarte w express.

Nie zapomnij również wysłać nagłówka Content-Type: application/json

rustyx
źródło
14
Dziękuję, to najlepsza odpowiedź na 4.16+. Żadnych innych zależności i działa jak urok!
Codepleb
1
Najlepsze / jedyne rozwiązanie, jakie udało mi się znaleźć, które nie wymaga parsera ciała
Mote Zart
41

Począwszy od Express 4, następujący kod wydaje się załatwiać sprawę. Pamiętaj, że musisz zainstalować body-parserza pomocą 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
źródło
29
Do parsowania ciał json wymagane jest dodanie następującego wierszaapp.use(bodyParser.json())
Camilo Silva
1
@ cml.co czy jest jakiś powód app.use(bodyParser.urlencoded({ extended: true })jest również wymagany? Wysyłam dość złożony dokument w postaci JSON w żądaniu i extended: falsenie zadziałało. Dopiero gdy ustawię wartość true, żądanie jest poprawnie analizowane.
Użytkownik sieciowy
3
Tylko uwaga. Musiał użyć app.use(bodyParser.urlencoded({ extended: true }));AND, app.use(bodyParser.json())aby uzyskać dane json na serwerze AWS Linux z konfiguracją NodeJS i 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);

To ci pomoże. Zakładam, że wysyłasz treść w formacie json.

Gautam
źródło
Zawsze zapominam o dodaniu bodyParser.json () bit x_x dzięki!
Jonny Asmar
14

W 2019 nie musisz instalować body-parser.

Możesz użyć:

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
źródło
8

Można to osiągnąć bez body-parseruzależnienia, jak również, słuchać request:datai request:endi zwróci odpowiedź na koniec wniosek, patrz poniżej próbki kodu. 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
źródło
3

Spróbuj tego:

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

To zabierze obiekt, który bodyParserdla ciebie utworzył, zamieni go z powrotem w łańcuch i zapisze go w odpowiedzi. Jeśli chcesz uzyskać dokładną treść żądania (z tą samą białą spacją itp.), Będziesz potrzebować datai endnasłuchiwaczy dołączonych do żądania wcześniej i zbudować fragment ciągu po kawałku, jak widać w json parsującym kod źródłowy z connect .

Peter Lyons
źródło
1

To, co twierdzisz, że „próbowałeś zrobić”, jest dokładnie tym, co napisałeś w kodzie, który działa „zgodnie z oczekiwaniami”, gdy wywołujesz to za pomocą curl.

Wyświetlany błąd nie wydaje się być powiązany z żadnym z przedstawionych nam kodów.

Jeśli chcesz dostać wniosek surowego ustaw teleskopowe na requestza datai endwydarzeń (i, oczywiście, usunąć wszelkie wywołania z express.bodyParser()). Zauważ, że datazdarzenia będą występować w fragmentach i jeśli nie ustawisz kodowania dla datazdarzenia, te fragmenty będą buforami, a nie ciągami.

ebohlman
źródło
to był błąd kopiuj-wklej; Miałem na myśli request.bodyi nie request.body.user, i teraz to poprawiłem. Nawiasem mówiąc, var reqBody = request.body;był i nadal jest poprawny, a kiedy spróbujesz, pojawi się błąd, który otrzymuję. W każdym razie, czy możesz podać przykład włączania programu obsługi request; Wydaje się, że nie znajduję tego w ekspresowym przewodniku.
TheBlueSky
1

Jeśli jesteś wystarczająco leniwy, aby czytać fragmenty danych postów. możesz po prostu wkleić poniższe wiersze, aby odczytać plik json.

Poniżej jest dla TypeScript, podobnie można zrobić dla 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 }));

W jednym z dowolnego kontrolera, który odbiera wywołanie POST, użyj, jak pokazano poniżej

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 powinien analizować dane json do modelu TS.

Shujaath Khan
źródło
1
Nie jestem pewien, czy próbujesz zachęcić lub zniechęcić ludzi do korzystania z Twojej odpowiedzi, nazywając ich leniwymi :)
TheBlueSky
1

Jestem absolutnie nowy w JS i ES, ale wydaje mi się, że działa tak:

JSON.stringify(req.body)

Daj mi znać, jeśli coś jest z tym nie tak!

balintn
źródło
dokładnie to, czego potrzebowałem
Josef Henn
0

Zainstaluj analizator treści za pomocą poniższego polecenia

$ npm install --save body-parser

Skonfiguruj analizator treści

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
źródło
-3

Używasz następującego kodu do logowania danych postów:

router.post("/users",function(req,res){
    res.send(JSON.stringify(req.body, null, 4));
});
Chandra Kumar
źródło
2
Podana odpowiedź jest niekompletna bez dołączenia modułu body-parser.
gramcha