2017-04-11 80 views
1

我已經瀏覽了很多其他帖子,我很迷惘。節點JS req.body undefined

我可以運行console.log(req),並得到下面的輸出

ServerResponse { 
    ... 
    req: 
    IncomingMessage { 
    ... 
    url: '/my-endpoint', 
    method: 'POST', 
    statusCode: null, 
    statusMessage: null, 
    ... 
    body: { foo: 'bar' }, 
    _body: true, 
    ... 
    route: Route { path: '/my-endpoint', stack: [Object], methods: [Object] } }, 
    ... 

看上去結實,所以我希望做console.log(req.body)並獲得{ foo: 'bar' }回到控制檯...但沒了,越來越不確定

經過研究,我發現它可能與我的app.js文件有關,特別是與body-parser,但是,我已經全部都是

var express = require('express'); 
var path = require('path'); 
var favicon = require('serve-favicon'); 
var logger = require('morgan'); 
var cookieParser = require('cookie-parser'); 
var bodyParser = require('body-parser'); 
var http = require('http'); 

var app = express(); 

// view engine setup 
app.set('views', path.join(__dirname, 'views')); 
app.set('view engine', 'pug'); 

app.use(logger('dev')); 
app.use(bodyParser.json()); 
app.use(bodyParser.urlencoded({ extended: false })); 
app.use(cookieParser()); 
app.use(express.static(path.join(__dirname, 'public'))); 

//Home Page Rendering 
var index = require('./routes/index'); 
app.use('/', index); 

// All other routes are kept in the `routes` module 
require('./routes')(app); 

module.exports = app; 

routes.js

module.exports = function routing(app) { 
    var apiClient = require('./services/apiClient'); 

    app.post('/get-device-info', function(err, req, res){ 
    console.log("/get-device-info routes"); 
    apiClient(req, res); 
    }); 
}; 

apiClient.js

module.exports = function callApi(req, res){ 
    console.log(req); 
    console.log(req.body) 
}; 

index.js

var express = require('express'); 
var router = express.Router(); 

/* GET home page. */ 
router.get('/', function(req, res, next) { 
    res.render('index', { title: 'Express' }); 
}); 

module.exports = router; 

這是我已經試過

app.use(express.bodyParser());

確保傳入的請求被明確聲明應用程序/ JSON

聲明在其他方面

添加配置功能

+0

您使用表達的版本?你可能希望堅持4.x和單獨的'body-parser'模塊,而不是'express.bodyParser'。你還可以包含索引路由功能嗎? –

+0

他確實堅持獨立的身體解析器... –

+0

我不知道爲什麼我被低估了這一點。向OP添加了更多代碼。我正在使用節點7.4.0並且表達4.15.0 –

回答

4

你的問題是,Express不使用error first callbacks體parser.json它的路由處理程序。下面的代碼將不起作用,因爲app.post處理程序沒有簽名(req, res) => {}。在下面的代碼中,err等於reqreq等於res,並且res等於next

// routes.js 
module.exports = function routing(app) { 
    var apiClient = require('./services/apiClient'); 

    app.post('/get-device-info', function(err, req, res){ 
    console.log("/get-device-info routes"); 

    // Assuming the request is correct 
    // the value of body will be the request body 
    console.log(res.body) 

    apiClient(req, res); 
    }); 
};` 

有3個可以在快速

使用
  • (req, res) => {}不同的路線回調簽名 - 這是最基礎和定義,只是關心請求和響應
  • (req, res, next) => {}的路線 - 這是中間件回調簽名,看起來像一個基本的路由回調,但它也分配next對象,告訴Express調用下一個匹配的路由。
  • (err, req, res, next) => {} - 這是錯誤處理路由回調,每個Express Router Middleware或Express App只需要1個。如果在路由或中間件內調用next(err),它會被調用。更具體地說,如果next()沒有用字符串或任何東西調用,它將跳過所有剩下的中間件和路由並直接進入錯誤處理程序。你可以閱讀更多關於它的Express Docs

你需要的路線定義修改爲

app.post('/get-device-info', (req, res) => { 
    apiClient(req, res) 
}) 

或者你甚至可以做到這一點

module.exports = app => { 
    let apiClient = require('./services/apiClient') 

    app.post('/get-device-info', apiClient) 
} 
+0

我知道這是愚蠢的這樣的.....我不認爲回調簽名順序重要。謝謝 –

0

試試這個,因爲它爲我工作。

首先聲明app然後bodyParser,因爲bodyParser是內app使用:

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

然後下面有這些行:

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