node.js tutorial Express.js req.body未定義



node.js express初入門下集 (14)

Content-Type in請求頭非常重要,尤其是當您從curl或任何其他工具發布數據時。

確保你使用的是像application / x-www-form-urlencoded,application / json或其他的東西,這取決於你的發布數據。 將此字段留空會使Express表示混淆。

我把它作為我的Express服務器的配置

app.use(app.router); 
app.use(express.cookieParser());
app.use(express.session({ secret: "keyboard cat" }));
app.set('view engine', 'ejs');
app.set("view options", { layout: true });
//Handles post requests
app.use(express.bodyParser());
//Handles put requests
app.use(express.methodOverride());

但仍然當我在我的路線中詢問req.body.something ,我發現一些錯誤指出body is undefined 。 以下是使用req.body的路線req.body

app.post('/admin', function(req, res){
    console.log(req.body.name);
});

我讀到,這個問題是由缺乏app.use(express.bodyParser()); 但正如你所看到的,我在路線之前叫它。

任何線索?


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

這節省了我的一天。


今天發生在我身上。 上述解決方案都不適用於我。 但是有一點google搜索幫助我解決了這個問題。 我為微信第三方服務器編碼。

當node.js應用程序需要讀取流式POST數據(例如來自REST客戶端的請求)時,情況會稍微複雜一些。 在這種情況下,請求的屬性“可讀”將被設置為true,並且POST數據必須分塊讀取才能收集所有內容。

http://www.primaryobjects.com/CMS/Article144


Express(4.x)的最新版本已將中間件從核心框架中分離出來。 如果你需要body parser,你需要單獨安裝

npm install body-parser --save

然後在您的代碼中執行此操作

var bodyParser = require('body-parser')
var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

浪費了很多時間:

取決於客戶請求中的內容類型
服務器應該有不同的,下面的app.use()之一:

app.use(bodyParser.text({ type: 'text/html' }))
app.use(bodyParser.text({ type: 'text/xml' }))
app.use(bodyParser.raw({ type: 'application/vnd.custom-type' }))
app.use(bodyParser.json({ type: 'application/*+json' }))

來源: https://www.npmjs.com/package/body-parser#bodyparsertextoptions : https://www.npmjs.com/package/body-parser#bodyparsertextoptions

例:

對我來說,在客戶端,我有下面的標題:

Content-Type: "text/xml"

所以,在服務器端,我使用了:

app.use(bodyParser.text({type: 'text/xml'}));

然後,req.body工作正常。


為了工作,您需要在app.use(express.bodyParser())之後app.use(app.router) ,如下所示:

app.use(express.bodyParser())
   .use(express.methodOverride())
   .use(app.router);

不需要。您需要在app.use(app.router)之前使用app.use(express.bodyParser()) app.use(app.router) 。 事實上, app.use(app.router)應該是你最後一次調用的東西。


如果您發布SOAP消息,則需要使用原始體分析器:

var express = require('express');
var app = express();
var bodyParser = require('body-parser');

app.use(bodyParser.raw({ type: 'text/xml' }));

express.bodyParser()需要被告知它解析的是什麼類型的內容。 因此,您需要確保在執行POST請求時包含“Content-Type”標題。 否則,bodyParser可能不知道如何處理POST請求的內容。

如果您使用curl執行包含正文中的某個JSON對象的POST請求,它看起來像這樣:

curl -X POST -H "Content-Type: application/json" -d @your_json_file http://localhost:xxxx/someRoute

如果使用其他方法,只要確保使用任何適當的約定來設置該頭字段。


看起來身體分析器不再使用快遞。 我們可能需要單獨安裝。

var express    = require('express')
var bodyParser = require('body-parser')
var app = express()

// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }))

// parse application/json
app.use(bodyParser.json())

// parse application/vnd.api+json as json
app.use(bodyParser.json({ type: 'application/vnd.api+json' }))
app.use(function (req, res, next) {
console.log(req.body) // populated!

有關更多信息和示例,請參閱git頁面https://github.com/expressjs/body-parser


感謝@spikeyang提供了很好的答案(如下所示)。 閱讀後附的建議文章後,我決定分享我的解決方案。

何時使用?

該解決方案要求您使用Express路由器才能享受它。如此:如果您嘗試使用接受的答案而沒有運氣,只需使用複制並粘貼此功能:

function bodyParse(req, ready, fail) 
{
    var length = req.header('Content-Length');

    if (!req.readable) return fail('failed to read request');

    if (!length) return fail('request must include a valid `Content-Length` header');

    if (length > 1000) return fail('this request is too big'); // you can replace 1000 with any other value as desired

    var body = ''; // for large payloads - please use an array buffer (see note below)

    req.on('data', function (data) 
    {
        body += data; 
    });

    req.on('end', function () 
    {
        ready(body);
    });
}

並稱之為:

bodyParse(req, function success(body)
{

}, function error(message)
{

});

注意:對於大型有效負載 - 請使用數組緩衝區( more @ MDN


您必須確保在定義路線之前定義所有配置。 如果你這樣做,你可以繼續使用express.bodyParser()

一個例子如下:

var express = require('express'),
    app     = express(),
    port    = parseInt(process.env.PORT, 10) || 8080;

app.configure(function(){
  app.use(express.bodyParser());
  app.use(app.router);
});

app.listen(port);

app.post("/someRoute", function(req, res) {
  console.log(req.body);
  res.send({ status: 'SUCCESS' });
});

建立在@ kevin-xue上說,內容類型需要聲明。 在我的例子中,這只發生在IE9上,因為XDomainRequest沒有設置內容類型 ,所以bodyparser和expressjs忽略了請求的主體。

我通過在將請求傳遞到主體解析器之前顯式設置content-type來解決此問題,如下所示:

app.use(function(req, res, next) {
    // IE9 doesn't set headers for cross-domain ajax requests
    if(typeof(req.headers['content-type']) === 'undefined'){
        req.headers['content-type'] = "application/json; charset=UTF-8";
    }
    next();
})
.use(bodyParser.json());

// Require body-parser (to receive post data from clients)

var bodyParser = require('body-parser');

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

// parse application/json

app.use(bodyParser.json())




express