Node.jsとExpressを使用してPOSTするときにリクエスト本文にアクセスするにはどうすればよいですか?


174

次の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();
});

今私が何かをPOSTした場合:

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

Someoneさすがにゲット。では、リクエスト本文全体を取得したい場合はどうすればよいですか?試してみましたresponse.write(request.body)が、Node.jsは「最初の引数は文字列またはバッファである必要があります」という例外をスローし、「送信後にヘッダーを設定できない」という例外を伴って「無限ループ」に進みます。これは私がvar reqBody = request.body;書いてから書いても同じresponse.write(reqBody)です。

ここの問題は何ですか?

また、使用せずにそのままのリクエストを取得できexpress.bodyParser()ますか?


何かがあるようresponse.write(reqBody)です。私が使用するときresponse.send(reqBody)は問題なく動作しています...そしてはい、私はresponse.end後に使用しresponse.writeます。
TheBlueSky

回答:


161

Express 4.0以降:

$ npm install --save body-parser

そして、あなたのノードアプリで:

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

Express 3.0以前:

これをcURL呼び出しで渡してみてください:

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

データがJSON形式であることを確認します。

{"user":"someone"}

また、次の例のように、node.jsコードでconsole.dirを使用して、オブジェクト内のデータを確認できます。

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

この他の質問も役立つかもしれません:エクスプレスnode.js POSTリクエストでJSONを受け取る方法は?

bodyParserを使用したくない場合は、次の質問を確認してください。https//stackoverflow.com/a/9920700/446681


使用しようとしましたcurl -d {"user":"Someone"} -H "Content-Type: application/json" --url http://localhost:5000が、「予期しないトークンu」というエラーが表示されたため、元の投稿で上記の呼び出しに切り替えました。
TheBlueSky


40
express.bodyParser()Express 4.xでは非推奨です。代わりにnpmjs.org/package/body-parserを使用してください。
Luc

@TheBlueSky「予期しないトークンu」を取得した理由は、シェルが二重引用符を消費したためです。そうした場合も同じことが起こりますecho any"thing"。あなたが投稿しているデータは、これが起こらないように引用符で囲んでください。
トムフェネック2017年

11
Express 4.16.0以降では、app.use()でexpress.json()を次のように使用できます=> app.use(express.json());
Mitro、2018年

187

始まっ急行v4.16だけ使用し、任意の追加のモジュールを必要とする必要はありません組み込みのJSONミドルウェア

app.use(express.json())

このような:

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

注- body-parserこれが依存するは、すでに Expressに含まれています。

また、ヘッダーを送信することを忘れないでください Content-Type: application/json


14
ありがとう、これが4.16以降の最良の答えです。他の依存関係はなく、魅力のように動作します!
codepleb

1
ボディパーサーを必要としない、私が見つけた最良/唯一のソリューション
Mote Zart

41

Express 4以降、次のコードでうまくいくようです。body-parserを使用してインストールする必要があることに注意してください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
jsonボディを解析するには、次の行を追加する必要がありますapp.use(bodyParser.json())
Camilo Silva

1
@ cml.coは何らかの理由があるapp.use(bodyParser.urlencoded({ extended: true })必要では?リクエストでJSONとしてかなり複雑なドキュメントを投稿していますが、機能extended: falseしませんでした。trueに設定した場合のみ、リクエストは正しく解析されます。
Webユーザー

3
ただのメモ。app.use(bodyParser.urlencoded({ extended: true }));AND を使用app.use(bodyParser.json())して、NodeJSとExpressを備えたAWS Linuxサーバーセットアップでjsonデータを取得する必要がありました。
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);

これはあなたを助けます。私はあなたがJSONでボディを送信していると思います。


bodyParser.json()ビットを追加するのをいつも忘れていますx_xありがとうございます!
Jonny Asmar

14

2019の場合、をインストールする必要はありませんbody-parser

以下を使用できます。

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

これはなしで達成することができbody-parser、同様の依存関係に耳を傾けるrequest:datarequest:end、要求の最後に応答を返し、コードサンプルの下に参照してください。参照: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

これを試して:

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

それはbodyParserあなたのために作成したオブジェクトを受け取り、それを文字列に戻し、それを応答に書き込みます。正確なリクエスト本文(同じ空白など)が必要な場合は、前にリクエストに添付されたリスナーが必要でdataあり、接続からのjson解析ソースコードでend確認できるように、チャンクごとに文字列チャンクを構築します。


1

「試してみた」と主張するのは、curlで呼び出したときに「期待どおりに」機能するコードで記述したとおりです。

表示されたエラーは、表示されたコードのいずれにも関連していないようです。

生のリクエストを取得したい場合requestは、dataおよびendイベントのハンドラーをオンに設定します(もちろん、の呼び出しを削除しますexpress.bodyParser())。dataイベントはチャンクで発生し、dataイベントのエンコーディングを設定しない限り、それらのチャンクは文字列ではなくバッファになることに注意してください。


それはコピーと貼り付けの間違いでした。という意味request.bodyではなくrequest.body.user、今修正しました。ちなみに、これはvar reqBody = request.body;今でも正しく、試してみるとエラーが発生します。とにかく、ハンドラーをに設定する例を教えてくださいrequest。エクスプレスガイドには載っていないようです。
TheBlueSky

1

投稿データのチャンクを読み取るのに十分な遅延がある場合。jsonを読むために、単に行の下に貼り付けることができます。

以下はTypeScriptの場合で、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 }));

以下に示すように、POSTコールを受信するいずれかのコントローラーで使用します。

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は、jsonデータをTSモデルに解析する必要があります。


1
人々を怠け者と呼んであなたの答えを使うように奨励したり阻止したりしようとしているのかどうかは
わかり

1

私はJSとESにまったく不慣れですが、私にとってうまくいくように見えるのはこれだけです:

JSON.stringify(req.body)

何か問題があれば教えてください!


まさに私が必要としていたもの
Josef Henn

0

以下のコマンドでBody Parserをインストールします

$ npm install --save 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

次のコードを使用して、投稿データをログに記録します。

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

2
与えられた答えは、body-parserモジュールを含まないと不完全です。
gramcha 2017
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.