对于API的GET请求,我为每种对象类型都有一个有效查询参数的对象。
var queryFields = {
'organisation': ['limit', 'page', 'id', 'search'],
'actor': ['limit', 'page', 'id', 'search'],
'version': ['limit', 'page', 'search'],
'product': ['limit', 'page', 'search', 'id', 'type', 'brand', 'model', 'manufacturerSpid'],
'asset': ['limit', 'page', 'search', 'order', 'sort', 'id', 'name', 'currentCustodianSpid', 'currentLocationSpid', 'productSpid', 'search'],
'location': ['limit', 'page', 'search', 'id'],
'workorder': ['limit', 'page', 'search', 'id', 'type', 'status', 'requirementSpid', ],
'move': ['limit', 'page', 'search'],
'transfer': ['limit', 'page', 'search'],
'requirement': ['limit', 'page', 'search', 'id', 'type', 'source', 'productSpid', 'status', ],
'artefact': ['limit', 'page', 'search'],
'attestation': ['limit', 'page', 'search'],
};我想使用这个函数来确保一个请求只接受这些有效的参数。现在,promise使用有效、无效或0参数来解析false。这似乎是我过滤方式的一个问题。我传入对象类型和请求。如果请求有查询参数,我希望从对象中获取有效参数,并检查req中的参数是否都与对象中的参数有效匹配。如果有任何是无效的,我想要解析false。如果没有参数,我想解析true。如果只有有效的参数,我想要解析true。为了得到这样的结果,我可以对这个函数做一些调整吗?
function getQueryFields(object) {
if (utils.isDefined(queryFields[object])) return queryFields[object];
return [];
}
function fieldValidator (objType, req) {
return new Promise(function(resolve) {
if (utils.isDefined(req.query)) {
var fields = getQueryFields(objType);
//Only resolve true with valid fields
fields = fields.filter(function(field) { return Object.keys(req.query).indexOf(field) > -1;});
if (Object.keys(req.query) !== Object.keys(fields)) {
resolve(false);
} else {
resolve (true);
}
} else {
resolve(true);
}
});
}发布于 2019-04-03 23:17:57
你的函数有一些问题。在进入实际问题之前,我想先解决第一个问题,因为这将大大提高清晰度。首先:你不需要Promise,这是一个同步函数。
重写#1:
function getQueryFields(object) {
if (utils.isDefined(queryFields[object])) return queryFields[object];
return [];
}
function fieldValidator (objType, req) {
if (utils.isDefined(req.query)) {
var fields = getQueryFields(objType);
//Only resolve true with valid fields
fields = fields.filter(function(field) {
return Object.keys(req.query).indexOf(field) > -1;
});
if (Object.keys(req.query) !== Object.keys(fields)) {
return false;
} else {
return true;
}
}
} else {
return true;
}这个函数可以使用的另一件事是“提前”返回。这使得跟踪正在发生的事情变得更容易,并减少了分支的数量:
重写#2:
function fieldValidator (objType, req) {
if (req.query === undefined) {
return true;
}
var fields = getQueryFields(objType);
//Only resolve true with valid fields
fields = fields.filter(function(field) {
return Object.keys(req.query).indexOf(field) > -1;
});
return (Object.keys(req.query) === Object.keys(fields));
}这些都不能回答您的问题,但我需要它来更清楚地了解您在做什么=)
问题实际上在于比较Object.keys()。Object.keys()返回一个迭代器,但它返回的每个迭代器都是唯一的。
Javascript中的对象不能真正“通过值”进行比较。通过值比较对象的唯一方法是逐个检查它们的键。
由于您希望属性完全匹配,我认为我应该将其更改为:
如果传递的每个查询参数都出现在有效查询参数集中,则
基于此,我认为这将是我的版本:
function fieldValidator(objType, req) {
if (!req.query || Object.keys(req.query).length === 0) {
// Covers the 'undefined' and 'empty object' case
return true;
}
const fields = getQueryFields(objType);
const keys = Object.keys(req.query);
// Do we have enough query parameters?
if (keys.length !== fields.length) return false;
// Does every query parameter appear in the list?
for(const key of keys) {
if (!fields.includes(key)) return false;
}
return true;
}发布于 2019-04-03 23:14:48
"Fields“是键名的数组。您将根据键名称数组的对象键检查req.query键的数组。这是数组的索引,只是连续的整数,["0", "1", "2", ... etc]。更不用说,你正在做两个数组之间的不等式检查,这永远不会是真的,除非引用是相同的,但它们不在这里。当然,第一个条件总是失败,并解析为false。在控制台中亲自尝试:[1, 2, 3] === [1, 2, 3]将为false (与宽松的相等性检查相同),因为它们是碰巧具有相同条目的不同对象。
所以我认为更好的方法是改变你的过滤器,让它过滤掉列表中的每个查询字段,并确保最终的数组没有条目(因为剩下的任何东西都是一个与列表不匹配的键)。
fields = Object.keys(req.query).filter(function(field) { return fields.indexOf(field) > -1;});
if (fields.length > 0) {
resolve(false);
} else {
resolve (true);
}(我假设您使用Promise有一个不可言说的原因;如果没有,我会采用Marcos Casagrande的建议,完全摆脱Promise,直接从函数返回true或false。)
发布于 2020-09-05 05:53:47
如果使用expressjs,有一个很好的方法是使用check api。
https://stackoverflow.com/questions/55498129
复制相似问题