在快速.js路由器函数中从 mongo 返回数据
Returning data from mongo within an express.js router function
我正在尝试编写一个简单的验证函数,该函数采用mongo_id并检查它是否存在。我能够走这么远,但我无法将该结果传递回调用该函数的路由。
这是基于一个四处浮动的示例的函数......它确实有效。
validateUserId = function(userId) {
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var options = {
mongos: {
ssl: false,
sslValidate: false,
}
}
isValid = false;
MongoClient.connect(vars["MONGO_URL"], options, function(err, db) {
assert.equal(null, err);
var q = db.collection("users").find({
_id: userId
}, {
_id: 1
}).toArray(function(err, record) {
assert.equal(null, err);
record.forEach(function(r) {
console.log(r);
if (r._id == userId) {
isValid = true;
}
});
db.close();
return isValid;
})
});
return isValid;
};
此函数不返回任何内容。
如何正确修改此代码以根据查询结果返回真/假值?
这个想法是不必将此代码放入需要进行验证的每个路由中,只需在执行其他任务(不需要访问或连接到mongodb)之前调用validateUserId()。
前任:
app.get("/performVerifiedAction",function(req,res){
if(validateUserId(req.query['userId'])){
res.send("You may pass");
}else{
res.send("Can't figure out who you are");
}
return true;
});
Node.js调用外部服务的方法是异步的。这意味着调用 MongoDb 函数不会阻止程序执行,因此您的 validateUserId 函数将始终返回 false,因为 MongoDb 查找回调将在很久以后调用,并且不会修改已经返回的值。
若要在许多路由上使用此验证,可以将此方法修改为 Express 中间件,如下所示:
//Avoid connecting to MongoDb on every request, make the connection persistant
var MongoClient = require('mongodb').MongoClient;
var options = {
mongos: {
ssl: false,
sslValidate: false,
}
};
var mongo = {
db: null
};
MongoClient.connect(vars["MONGO_URL"], options, function(err, db) {
if (err) {
console.error("Error connecting to MongoDB:", err);
process.exit(1);
}
mongo.db = db;
});
// Create a middleware method that will be called in request processing chain before your handler
var validateUserId = function(req, res, next) {
var userId = req.query['userId'];
// Use findOne to validate user id. It is faster and simplier
mongo.db.collection("users").findOne({_id: userId}, {_id: 1}, function(err, record) {
if (err) {
return res.status(500).send("Error getting user");
}
if (!record) {
return res.status(403).send("Can't figure out who you are");
}
next();
});
};
然后,您可以通过以下方式使用此中间件:
app.get("/performVerifiedAction", validateUserId, function(req,res){
res.send("You may pass");
});
validUserId
实际上是一个异步函数。
在其最后一个参数中接收回调,请参阅如何为 Node 编写异步函数.js
在 Node.js 样式回调之后,callback
参数是一个函数,它在其第二个参数中接收异步操作的结果。
// callback is a function that gets isValid as its second arguments
// by convention the first argument of these callback function is any error
// that may occur in this async operation.
validateUserId = function(userId, callback) {
var MongoClient = require('mongodb').MongoClient;
var assert = require('assert');
var options = {
mongos: {
ssl: false,
sslValidate: false,
}
}
isValid = false;
MongoClient.connect(vars["MONGO_URL"], options, function(err, db) {
assert.equal(null, err);
var q = db.collection("users").find({
_id: userId
}, {
_id: 1
}).toArray(function(err, record) {
assert.equal(null, err);
record.forEach(function(r) {
console.log(r);
if (r._id == userId) {
isValid = true;
}
});
db.close();
return callback(null, isValid); // instead of return isValid;
})
});
return callback(null, isValid); // instead of return isValid;
};
这是如何使用validUserId
异步功能:
app.get("/performVerifiedAction",function(req,res){
validateUserId(req.query['userId'], function(error, isValid) {
if(isValid) {
res.send("You may pass");
} else {
res.send("Can't figure out who you are");
}
});
});
请注意,您可以通过处理错误(将err
传递给callback
并从函数返回)来大大改进上述代码。例如:
MongoClient.connect(vars["MONGO_URL"], options, function(err, db) {
assert.equal(null, err);
// ...
可以改进为:
MongoClient.connect(vars["MONGO_URL"], options, function(err, db) {
if(!!err) {
return callback(err);
}
//...
相关文章:
- 从mongo返回的对象(findOne)中筛选/返回单个嵌套对象
- 当查询返回对象时,Express Mongo回调返回undefined
- 如何在Mongo中访问group reduce返回的数据
- 在快速.js路由器函数中从 mongo 返回数据
- Mongo 查询以从集合数组返回特定值
- 通过 Meteor / Mongo 返回子文档数组
- Mongo 返回未定义但数据存在
- 在 Meteor React 应用程序中使用 Mongo 集合时,返回一个空数组 []
- 如何使用猫鼬操作从 mongo db 返回的数据
- Mongo DB,Node Express,从MongoDB返回的输出中提取一个元素
- 输出从 mongo 到 jade 的返回数据
- Mongo:执行collection.find()返回主节点上的所有项是一种好的做法吗
- 如何从发送给Mongo的脚本中返回值
- 为什么new Date在mongo shell中返回无效,而在Node REPL中返回有效日期?
- 异步返回已插入post的_id到Mongo collection中
- 从mongo返回纯json对象的问题
- 如何在javascript中操作返回的mongo集合/游标(meteor.js)
- Mongo查找选择器返回不匹配的结果
- 在Angular中使用$http POST时,返回mongo ObjectID
- Mongoose返回Mongo对象,但是不能访问它的属性