Node.js(express)是否可以实现不区分大小写的查询字符串?

14

看起来查询字符串是大小写敏感的。有没有可能拥有一个大小写不敏感的查询字符串呢?

如果我的url有?Id=10,访问req.query.id将返回undefined

3个回答

28
无法直接实现,但您可以插入一个非常简单的中间件,例如将req.query中的所有键转换为小写:
// insert this before your routes
app.use(function(req, res, next) {
  for (var key in req.query)
  { 
    req.query[key.toLowerCase()] = req.query[key];
  }
  next();
});

1
谢谢!从IIS过来,感觉很奇怪,这样基本的要求竟然被忽视了。 - Amitava
2
如果用户输入的查询参数大小写混合怎么办? :) - Amitava
1
是的。我可能会访问 example.com?bookid=1,而服务器期望的是 ?bookId=1,这是一个非常常见的情况。 - Amitava
1
如果这对你来说是一个常见的情况(对我来说不是),我完全理解你需要一种不区分大小写的访问这些参数的方式 :) - robertklep
1
@robertklep,如果我没记错的话,我们最终会得到双倍的属性.. 对吧。 - refactor
显示剩余3条评论

14

使用Robert提出的解决方案时,请注意每当您从req.query中进行读取时,都需要使用小写键。这会使将来对API的添加容易出错。

这里有一种替代的中间件,使用代理对象修改req.query[...]的行为,使查找不区分大小写:

app.use((req, res, next) => {
  req.query = new Proxy(req.query, {
    get: (target, name) => target[Object.keys(target)
      .find(key => key.toLowerCase() === name.toLowerCase())]
  })

  next();
});

采用这种方法不仅减少了错误的可能性,而且还保留了req.query以枚举操作,而原始解决方案则可能会创建重复的键/值对。


请记得在最后一个条件中返回 target[name],否则 Object 方法(如 query.toString())将会抛出错误。 - ktutnik

0
如果参数和其值都需要不区分大小写地处理,那么有一个简单的方法:
const express = require('express');
const qs = require('qs');
const app = express();

app.set('query parser', function(str) {
    // See https://github.com/ljharb/qs/blob/410bdd3c8ae7f5d7ae9b52648b8642b8adc5e1c0/dist/qs.js#L47 
    return qs.parse(typeof str === 'string' ? str.toUpperCase() : str, {});
});

也就是说,在解析查询字符串之前,将整个查询字符串简单地转换为大写(或小写,根据您的喜好)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接