首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在node.js中验证REST api请求的查询参数

在node.js中验证REST api请求的查询参数
EN

Stack Overflow用户
提问于 2019-04-03 22:52:49
回答 3查看 4.2K关注 0票数 0

对于API的GET请求,我为每种对象类型都有一个有效查询参数的对象。

代码语言:javascript
复制
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。为了得到这样的结果,我可以对这个函数做一些调整吗?

代码语言:javascript
复制
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);
    }
  });
}
EN

回答 3

Stack Overflow用户

发布于 2019-04-03 23:17:57

你的函数有一些问题。在进入实际问题之前,我想先解决第一个问题,因为这将大大提高清晰度。首先:你不需要Promise,这是一个同步函数。

重写#1:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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中的对象不能真正“通过值”进行比较。通过值比较对象的唯一方法是逐个检查它们的键。

由于您希望属性完全匹配,我认为我应该将其更改为:

如果传递的每个查询参数都出现在有效查询参数集中,则

  1. 检查您是否具有相同数量的查询参数。

基于此,我认为这将是我的版本:

代码语言: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;
}
票数 1
EN

Stack Overflow用户

发布于 2019-04-03 23:14:48

"Fields“是键名的数组。您将根据键名称数组的对象键检查req.query键的数组。这是数组的索引,只是连续的整数,["0", "1", "2", ... etc]。更不用说,你正在做两个数组之间的不等式检查,这永远不会是真的,除非引用是相同的,但它们不在这里。当然,第一个条件总是失败,并解析为false。在控制台中亲自尝试:[1, 2, 3] === [1, 2, 3]将为false (与宽松的相等性检查相同),因为它们是碰巧具有相同条目的不同对象。

所以我认为更好的方法是改变你的过滤器,让它过滤掉列表中的每个查询字段,并确保最终的数组没有条目(因为剩下的任何东西都是一个与列表不匹配的键)。

代码语言:javascript
复制
  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。)

票数 0
EN

Stack Overflow用户

发布于 2020-09-05 05:53:47

如果使用expressjs,有一个很好的方法是使用check api。

https://express-validator.github.io/docs/check-api.html

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55498129

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档