【问题标题】:Node JS req.body undefined节点 JS req.body 未定义
【发布时间】:2019-07-16 11:15:06
【问题描述】:

我浏览了很多其他帖子,对此我很迷茫。

我可以运行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());

确保传入的请求明确声明 application/json

以其他方式声明body parser.json

添加配置函数

【问题讨论】:

  • 您使用的是哪个版本的 Express?您可能希望坚持使用 4.x 和单独的 body-parser 模块,而不是 express.bodyParser。能否也包含索引路由功能?
  • 他确实坚持使用单独的 body-parser...
  • 我不知道为什么我在这件事上被否决了。向 OP 添加了更多代码。我正在使用节点 7.4.0 并表示 4.15.0
  • 请在服务器处理请求头之前包含发送到服务器的请求头。 (浏览器的网络标签)

标签: node.js express


【解决方案1】:

您的问题是 Express 没有将 error first callbacks 用于其路由处理程序。下面的代码不起作用,因为app.post 处理程序没有签名(req, res) => {}。在下面的代码中err 等于reqreq 等于resres 等于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);
  });
};`

您可以在 Express 中使用 3 种不同的路由回调签名

  • (req, res) => {} - 这是最基本的,定义了一个只关心请求和响应的路由
  • (req, res, next) => {} - 这是中间件回调签名,看起来像一个基本的路由回调,但它还分配了 next 对象,告诉 Express 调用下一个匹配的路由。
  • (err, req, res, next) => {} - 这是错误处理路由回调,每个 Express 路由器中间件或 Express 应用程序只需要 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)
}

【讨论】:

  • 我知道这很愚蠢......我认为回调签名顺序并不重要。谢谢
【解决方案2】:

试试这个,因为它对我有用。

首先声明app,然后声明bodyParser,因为bodyParserapp中使用:

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

然后在下面有这些行:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-04
    • 1970-01-01
    • 1970-01-01
    • 2020-04-14
    • 1970-01-01
    • 2019-01-28
    • 1970-01-01
    • 2016-10-18
    相关资源
    最近更新 更多