【问题标题】:Why am I getting "name undefined" when trying to post using Express and Body Parser为什么我在尝试使用 Express 和 Body Parser 发帖时得到“名称未定义”
【发布时间】:2016-11-09 04:55:08
【问题描述】:

我正在尝试构建一个 MEAN 应用程序并尝试使用 POSTMAN 测试 POST。当我这样做时,我不断收到可怕的“TypeError:无法读取未定义的属性'名称'”。如果我输入一个简单的字符串,则 POST 可以正常运行。但是当我使用“req.body.name”时,我得到了错误。我已经查看了每个地方,但我没有看到我的错误。我什至没有运气就遵循了thread 的建议。任何帮助或建议将不胜感激。

这是我目前在 server.js 文件中使用的代码:

    const express = require('express');
var bodyParser = require('body-parser');
var Bear = require('./models/bear')
var path = require('path');
var mongoose = require('mongoose');
var router = express.Router();

var app = express();


var staticAssets = __dirname + '/public';

    app.use(express.static(staticAssets));


    app.use('/api', router)
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({extended: true}));


// Routes for my API
//===================================

// middleware to use for all requests
router.use(function(req,res,next){
    // logging happens here
    console.log('Something will happen.');
    next(); // Head to the next router...don't stop here
});

// Test router to make sure everything is working (accessed at GET http://localhost:3000/api)
router.get('/', function(req, res){
    res.json({message: 'hooray! welcome to our api!'})
})

//More routes will happen here with routes that end in "/bears"
router.route('/bears')
    //Create a bear (accessed at POST http://localhost:3000/api/bears)
    .post(function(req,res){
        var bear = new Bear(); // Create a new instance of the bear model
        console.log(req);
        bear.name = req.body.name; // set the bears name (comes from the request)

        //res.send(200, req.body);
        bear.save(function(err){
            if (err)
                res.send(err);
            res.json({message: 'Bear Created!!'});
        });
    });
//======================================

//var Products = require('./products.model.js');
var Product = require('./models/product.model');

var db = 'mongodb://localhost/27017';

mongoose.connect(db);







    var server = app.listen(3000);
console.log("App is listening on port 3000");

谢谢。

另外,我在 POSTMAN 中尝试使用的网址是 http://localhost:3000/api/bears

【问题讨论】:

  • 您应该在问题中包含您的客户请求。另一件事是您应该在所有路由和路由器中间件之前移动您的app.use(bodyParser.json())app.use(bodyParser.urlencoded({extended: true}))。如果它没有出现在它们之前,那么在处理这些路由时将不会使用它。因此,如果您请求 /api 路由器中间件,则不会使用 bodyParser

标签: node.js express postman


【解决方案1】:

Express 处理请求自上而下,这意味着如果您需要通过中间件将某个功能应用于所有路由,则需要将该中间件添加到您的应用中任何需要它的路由之前. body-parser 等中间件通常是这种情况。

使用路由器中间件时,您通常不会在与将其用作中间件的实际 Express 应用程序相同的文件中构建路由器。相反,将其放在单独的文件和/或目录中以用于组织目的,这被认为是最佳做法。

Express 应用程序可以这样构造

/lib
  /models
    bear.js
    product.js
/node_modules
/public
  /css    
/routes
  api.js
package.json
server.js

routes 目录是您放置任何适用的路由器中间件文件的地方,例如您的api 路由器。 server.js 是您的主要 Express 应用程序,public 是您存储静态资产的位置。 lib 是包含任何业务逻辑文件和模型的目录。

实际的 Express 应用和路由器文件应如下所示

server.js

'use strict';

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

const apiRouter = require('./routes/api');

const app = express();

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

app.use(express.static(path.join(__dirname, public)));

app.use(/api, apiRouter);

app.listen(port, () => {
    console.log(`Listening on port ${port});
});

module.exports = app; 

路由/api.js

'use strict';

const router = require('express').Router();
const Bear = require('./lib/models/bear');

router.use((req, res, next) => {
    // logging happens here
    console.log('Something will happen.');
    next(); // Head to the next router...don't stop here
});

router.get('/', (req, res) => {
    return res.json({ message: 'hooray! welcome to our api!'})
});

router.route('/bears')
    //Create a bear (accessed at POST http://localhost:3000/api/bears)
    .post((req, res) => {
        var bear = new Bear(); // Create a new instance of the bear model

        console.log(req);
        bear.name = req.body.name; // set the bears name (comes from the request)

        //res.send(200, req.body);
        bear.save((err) => {
            if (err)
                return res.send(err);

            return res.json({message: 'Bear Created!!'});
        });
    });

module.exports = router;

请注意,您可以进一步分解 API 以增加解耦量。这方面的一个例子是将/api/bear 路由移动到它自己的路由器中间件和它自己的路由文件中。然后只需将它作为中间件添加到您的routes/api.js 路由器中,就像在server.js 中一样。如果您的应用程序将有一个大小合适的 API,那么这将是最好的方法,因为在将中间件仅应用于某些路由时,它可以提供最大的灵活性,并且会使源代码的维护变得更加容易。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-03
    • 2018-08-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    相关资源
    最近更新 更多