Javascript 使用body解析器和express解析嵌套JSON

Javascript 使用body解析器和express解析嵌套JSON,javascript,node.js,mongodb,mongoose,body-parser,Javascript,Node.js,Mongodb,Mongoose,Body Parser,我有一个iOS应用程序正在向Web服务器发送JSON数据包。Web服务器代码如下所示: var express = require('express'); var bodyParser = require('body-parser'); var mongoose = require('mongoose'); var app = express(); mongoose.connect('mongodb://localhost/test'); var db = mongoose.connectio

我有一个iOS应用程序正在向Web服务器发送JSON数据包。Web服务器代码如下所示:

var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
mongoose.connect('mongodb://localhost/test');

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
  console.log("MongoDB connection is open.");
});

// Mongoose Schema definition
var Schema = mongoose.Schema;
var LocationSchema = new Schema({
    X: Number,
    Y: Number,
    Orientation: Number,
    UserID: String,
    Time: String
});

// Mongoose Model definition
var LocationsCollection = mongoose.model('locations', LocationSchema);

// create application/json parser
var jsonParser = bodyParser.json();

// URL management
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
});

app.post('/update', jsonParser, function (req, res) {
    if (!req.body) return res.sendStatus(400);
    else {
        console.log(req.body);
    }
});

// Start the server
var server = app.listen(3000, function () {
  var host = server.address().address
  var port = server.address().port
  console.log('App listening at %s:%s',host, port)
});
{ 
  datapoint_1:
   { timestamp: '2015-02-06T13:02:40:361Z',
     x: 0.6164286615466197,
     y: -0.6234909703424794,
     id: 'B296DF8B-6489-420A-97B4-6F0F48052758',
     orientation: 271.3345946652066 },
  datapoint_2:
   { timestamp: '2015-02-06T13:02:40:961Z',
     x: 0.6164286615466197,
     y: -0.6234909703424794,
     id: 'B296DF8B-6489-420A-97B4-6F0F48052758',
     orientation: 273.6719055175781 }
}
app.post('/update', jsonParser, function (req, res) {
    if (!req.body) return res.sendStatus(400);
    else {
        for(var datapoint in req.body){
            //create new instance of LocationCollection document
            var point = new LocationsCollection({
                X:Number(req.body[datapoint]["x"]),
                Y:Number(req.body[datapoint]["y"]),
                Orientation:Number(req.body[datapoint]["orientation"]),
                Time:req.body[datapoint]["timestamp"],
                UserID:req.body[datapoint]["id"]
            });
            //insert the newly constructed document into the database
            point.save(function(err, point){
                if(err) return console.error(err);
                else console.dir(point);
            });
        }
    }
});
关键部分是app.post方法,它处理从iOS应用程序发送的传入http请求。目前,将req.body打印到控制台的方法如下所示:

var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
mongoose.connect('mongodb://localhost/test');

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
  console.log("MongoDB connection is open.");
});

// Mongoose Schema definition
var Schema = mongoose.Schema;
var LocationSchema = new Schema({
    X: Number,
    Y: Number,
    Orientation: Number,
    UserID: String,
    Time: String
});

// Mongoose Model definition
var LocationsCollection = mongoose.model('locations', LocationSchema);

// create application/json parser
var jsonParser = bodyParser.json();

// URL management
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
});

app.post('/update', jsonParser, function (req, res) {
    if (!req.body) return res.sendStatus(400);
    else {
        console.log(req.body);
    }
});

// Start the server
var server = app.listen(3000, function () {
  var host = server.address().address
  var port = server.address().port
  console.log('App listening at %s:%s',host, port)
});
{ 
  datapoint_1:
   { timestamp: '2015-02-06T13:02:40:361Z',
     x: 0.6164286615466197,
     y: -0.6234909703424794,
     id: 'B296DF8B-6489-420A-97B4-6F0F48052758',
     orientation: 271.3345946652066 },
  datapoint_2:
   { timestamp: '2015-02-06T13:02:40:961Z',
     x: 0.6164286615466197,
     y: -0.6234909703424794,
     id: 'B296DF8B-6489-420A-97B4-6F0F48052758',
     orientation: 273.6719055175781 }
}
app.post('/update', jsonParser, function (req, res) {
    if (!req.body) return res.sendStatus(400);
    else {
        for(var datapoint in req.body){
            //create new instance of LocationCollection document
            var point = new LocationsCollection({
                X:Number(req.body[datapoint]["x"]),
                Y:Number(req.body[datapoint]["y"]),
                Orientation:Number(req.body[datapoint]["orientation"]),
                Time:req.body[datapoint]["timestamp"],
                UserID:req.body[datapoint]["id"]
            });
            //insert the newly constructed document into the database
            point.save(function(err, point){
                if(err) return console.error(err);
                else console.dir(point);
            });
        }
    }
});

因此,您可以看到请求是一个嵌套的JSON对象。理想情况下,我希望遍历请求对象(即数据点)并将它们插入mongoDB数据库(通过mongoose)。然而,我似乎不知道如何使用req.body做很多事情。我似乎无法创建循环来迭代请求,也无法正确解析嵌套的JSON文件以使其与mongoose模式匹配。有人能提供一些关于如何将这些数据点插入mongoose数据库的指导吗?

试试这样的方法

var app = express();
var bodyParser   = require('body-parser');
app.use(bodyParser.json({limit:1024*1024, verify: function(req, res, buf){
    try {
        JSON.parse(buf);
    } catch(e) {
        res.send({
            error: 'BROKEN_JSON'
        });
    }
}}));

回答我自己的问题。但是,在弄清楚如何访问嵌套JSON对象中的键/值对之后。。。剩下的就相对容易弄清楚了。更新后的app.post函数现在如下所示:

var express = require('express');
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var app = express();
mongoose.connect('mongodb://localhost/test');

var db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', function (callback) {
  console.log("MongoDB connection is open.");
});

// Mongoose Schema definition
var Schema = mongoose.Schema;
var LocationSchema = new Schema({
    X: Number,
    Y: Number,
    Orientation: Number,
    UserID: String,
    Time: String
});

// Mongoose Model definition
var LocationsCollection = mongoose.model('locations', LocationSchema);

// create application/json parser
var jsonParser = bodyParser.json();

// URL management
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
});

app.post('/update', jsonParser, function (req, res) {
    if (!req.body) return res.sendStatus(400);
    else {
        console.log(req.body);
    }
});

// Start the server
var server = app.listen(3000, function () {
  var host = server.address().address
  var port = server.address().port
  console.log('App listening at %s:%s',host, port)
});
{ 
  datapoint_1:
   { timestamp: '2015-02-06T13:02:40:361Z',
     x: 0.6164286615466197,
     y: -0.6234909703424794,
     id: 'B296DF8B-6489-420A-97B4-6F0F48052758',
     orientation: 271.3345946652066 },
  datapoint_2:
   { timestamp: '2015-02-06T13:02:40:961Z',
     x: 0.6164286615466197,
     y: -0.6234909703424794,
     id: 'B296DF8B-6489-420A-97B4-6F0F48052758',
     orientation: 273.6719055175781 }
}
app.post('/update', jsonParser, function (req, res) {
    if (!req.body) return res.sendStatus(400);
    else {
        for(var datapoint in req.body){
            //create new instance of LocationCollection document
            var point = new LocationsCollection({
                X:Number(req.body[datapoint]["x"]),
                Y:Number(req.body[datapoint]["y"]),
                Orientation:Number(req.body[datapoint]["orientation"]),
                Time:req.body[datapoint]["timestamp"],
                UserID:req.body[datapoint]["id"]
            });
            //insert the newly constructed document into the database
            point.save(function(err, point){
                if(err) return console.error(err);
                else console.dir(point);
            });
        }
    }
});
我可以通过在mongodb连接首次建立后将以下方法放入回调函数来测试这是否有效:

//Find all location points and print to the console.
console.log("Searching for all documents in Location Points Collection");
LocationsCollection.find(function(err,data){
    if(err) console.error(err);
    else console.dir(data);
});

这将打印以前添加到数据库中的所有文档。希望这会有所帮助。

这应该是一个简单的
(obj中的var键)
循环:

app.post('/update', jsonParser, function (req, res) {

    var locationObject = req.body(),
        insertObjects = [],
        key;

    for (key in locationObject) { // loop through each object and insert them into our array of object to insert.
        insertObjects.push(locationObject[key]); 
    }
    if (!insertObjects.length) { // if we don't have any object to insert we still return a 200, we just don't insert anything.
        return res.status(200).send({
            success: true,
            message: 'Nothing inserted, 0 locations in POST body',
            count: 0;
        });
    }
    LocationsCollection.create(insertObjects, function (err, res) {
        if (err) {
            return res.status(400).send({
                success: false,
                message: err.message
            });
        }
        // we have successfully inserted our objects. let's tell the client.
        res.status(200).send({ 
            success: true,
            message: 'successfully inserted locations',
            count: insertObjects.length;
        });
    });
});
Mongo允许通过一个回调插入多个文档,这使得插入变得更加容易

这还会检查架构,以确保只创建正确的文档。

扩展的
属性设置为
,以允许解析嵌套对象

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

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

您可能必须使用
JSON.parse
解析JSON,如果它仍然是一个string@adeneo你能澄清一下吗?我假设body解析器中间件已经将字符串解析为JSON对象。那么,试试看,做
typeof req.body
,我猜你会得到
string
@adeneo,它作为
对象
而不是
字符串
。这不意味着它是一个JSON对象吗?如果它是一个JSON对象,由于它是一个嵌套的JSON对象,您能否建议如何正确处理它(以便能够将其插入数据库?
for(var key in obj){…}
如果它确实是答案,您可以接受您的答案。