Client Error: bad object in message: bson length doesn't match what we found

Client Error: bad object in message: bson length doesn't match what we found

我在将数据发布到利用 Mongoose 和 MongoDB 的 Node/Express API 时遇到问题。尝试使用此架构、数据和处理程序进行批量插入时:

// Mongoose schema
var NotificationSchema = new Schema({
    uuid: {
        type: String,
        required: true,
        index: true
    },
    message: {
        type: String,
        required: true
    },
    url: {
        type: String,
        required: true
    }
});

// sample data
[
    {
        'uuid': '34e1ffef49ad4001bb9231c21bdb3be7',
        'url': '/polls/4666386cb92348af93417e9abb9ce880/forecast/',
        'message': '@btaylor has shared a poll with you'
    },
    {
        'uuid': '42d6a9f4b3f5416b952452c26e01789a',
        'url': '/polls/4666386cb92348af93417e9abb9ce880/forecast/',
        'message': '@btaylor has shared a poll with you'
    }
]

// route handler
Notification.prototype.bulkInsert = function(data, callback) {
    NotificationSchema.collection.insert(data, function(error, documents) {
        if (error) { return callback(error, null); }

        if (documents.length == 0) { return callback(null, null); }

        callback(null, documents);
    });
};

当通过邮递员发布为 x-www-form-urlencoded 时,我收到了回复:

{ [MongoError: Client Error: bad object in message: bson length doesn't match what we found]
  name: 'MongoError',
  err: 'Client Error: bad object in message: bson length doesn\'t match what we found',
  code: 10307,
  n: 0,
  connectionId: 125,
  ok: 1 }

我的 Mocha 测试 post 使用相同的数据工作得很好。我做错了什么?

[更新]

经过进一步测试,当使用请求库从我的 Django Web 应用程序中 post 时,请求正文似乎未正确解析。

我的 post 构造为:

requests.post(url, data=data)

其中 data 是一个 Python 字典:

{'data': [{'url': '/polls/4666386cb92348af93417e9abb9ce880/forecast/', 'message': '@btaylor has shared a poll with you', 'uuid': '34e1ffef49ad4001bb9231c21bdb3be7'}, {'url': '/polls/4666386cb92348af93417e9abb9ce880/forecast/', 'message': '@btaylor has shared a poll with you', 'uuid': '42d6a9f4b3f5416b952452c26e01789a'}]}

上述路由处理程序收到的 data 参数是从 req.body.data 填充的。在我的 Express 中间件中,我使用了以下正文解析器:

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

但是,根据 Django/requests 编辑的 post 记录请求正文会导致:

[ 'url', 'message', 'uuid', 'url', 'message', 'uuid' ]

为什么要删除值以及定义对象的大括号? post 的内容类型被正确报告为:

application/x-www-form-urlencoded

有人有什么想法吗?这对 Postman 来说非常有效,顺便说一句。

原来 Python 端有一个问题,Express 端有一个问题。

我从 Python 发布的对象列表在设置为发布的值之前需要转换为 JSON 字符串:

# views.py
notifications = json.dumps([{"uuid": profile.uuid_str,
    "message": message, "url": poll_forecast_url}
    for profile in shared_with])

requests.post(url, data={'data': notifications})

在我的问题前面,您会注意到我指出 Postman 的测试失败了。这是因为当在 Postman 选项中设置编码 x-www-form-urlencoded 时,Express 端的 req.body.data 值被作为字符串接收。为了解决这个问题,我在 Notification.bulkInsert() 函数调用之前添加了这一行:

var data = typeof(req.body.data) == 'string' ? JSON.parse(req.body.data) : req.body.data;

在将 JSON 字符串传递给 .bulkInsert()

之前将其正确转换为对象