2017-04-11 129 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}))