【问题标题】:Conventions for querystring parameters查询字符串参数的约定
【发布时间】:2013-01-26 21:45:23
【问题描述】:

当我有这样的网址时:

http://server/site?firstname=Jack&lastname=Daniels

我知道在我的 JavaScript 中,对名字的查询应该返回“Jack”。

但是在以下情况下,查询 firstname 应该返回什么:

http://server/site?lastname=Daniels
http://server/site?firstname&lastname=Daniels
http://server/site?firstname=&lastname=Daniels

[编辑]回答一些cmets:以上都是合法的查询字符串,我的问题不是关于如何检索参数而是如何解释它们。

作为记录,我使用以下涵盖所有情况的正则表达式解析查询字符串:

/([^?=&;]+)(?:=([^&;]*))?/g

显然有a very popular question on how to retrieve querystring parameters,但答案不正确(或者至少没有解决边缘情况)。

[更新]我根据@Bergi 和@zzzzBov 的回答做出的选择:

http://server/site?lastname=Daniels                => firstname: undefined
http://server/site?firstname&lastname=Daniels      => firstname: true
http://server/site?firstname=&lastname=Daniels     => firstname: ""
http://server/site?firstname=Jack&lastname=Daniels => firstname: "Jack"

一个副作用是我不得不稍微修改我的正则表达式,就像上面的规则一样,= 符号需要被捕获:

/([^?=&;]+)(=[^&;]*)?/g

【问题讨论】:

  • 获取查询字符串数据,同时可以忽略无效的查询字符串参数,显示有效参数的结果集
  • 就个人而言,我一直使用这个函数:stackoverflow.com/questions/901115/…

标签: javascript html url query-string


【解决方案1】:

但是在以下情况下,查询 firstname 应该返回什么:

http://server/site?lastname=Daniels
http://server/site?firstname&lastname=Daniels
http://server/site?firstname=&lastname=Daniels

查询字符串可以很容易地用 JavaScript 中的对象表示法来表示。只需在对象上仅设置查询字符串中存在的键即可。

这意味着对于?lastname=Daniels,生成的对象应该是:

{
    lastname: 'Daniels'
}

如果存在键,但没有给出值(没有等号),则应将键设置为值null,表示“无值”。

这意味着对于?firstname&lastname=Daniels,生成的对象应该是:

{
    firstname: null,
    lastname: 'Daniels'
}

如果存在键,并且提供的值为空(等号),则该值实际上是空字符串。

这意味着对于?firstname=&lastname=Daniels,生成的对象应该是:

{
    firstname: '',
    lastname: 'Daniels'
}

还有一个经常被忽视的情况,即多次使用同一个密钥。在传统的查询字符串语法(不是 PHP)中,可以按原样多次使用键来表示数组。

这意味着对于?foo=bar&foo=baz,生成的对象应该是:

{
    foo: [
        'bar',
        'baz'
    ]
}

在 PHP 领域,用于数组的键以 [] 为后缀:

`?foo[]=bar&foo[]=baz`

PHP 将自动转换查询字符串服务器端:

$_GET['foo'] = array('bar', 'baz')

回到最初的问题,这意味着以下内容:

  • 对于 firstname 键,?lastname=Daniels 的值为 undefined
  • 对于 firstname 键,?firstname&lastname=Daniels 的值为 null
  • 对于 firstname 键,?firstname=&lastname=Daniels 的值为 ''

对于根据其存在将键用作布尔值的情况,您应该检查对象是否具有键集(并完全忽略该值,因为这无关紧要)。

通常这是使用obj.hasOwnProperty('key') 完成的,但是由于对象实际上更像是一个哈希Object.prototype.hasOwnProperty.call(obj, 'key') is preferrable,可以将其抽象为has 函数:

has(obj, key) {
    return Object.prototype.hasOwnProperty.call(obj, key);
}

如果您使用的是underscore.js,那么您可以使用_.has(obj, key)

【讨论】:

  • @Christophe,Bergi 对布尔键的使用提出了一个很好的观点,但是如果您使用查询字符串的对象表示,则应该使用 obj.hasOwnProperty('key') 来检查键是否存在在对象中。实际上,即使这样也是错误的,you should really be using something like has(obj, 'key')
【解决方案2】:

但是查询应该返回什么

这是你的决定,你需要什么?有几个不同复杂度的查询字符串评估函数。其中一些可以处理重复的、嵌套的、括号语法值,而另一些则不能。著名的可以在How can I get query string values in JavaScript? 及其重复问题中找到。

但是,您要求约定:

http://server/site?lastname=Daniels

结果应该是虚假的,表示不存在firstName。您可以选择nullundefined

http://server/site?firstname&lastname=Daniels

这通常表示一些布尔参数,因此返回true 是合法的。但我确信有些库完全忽略了这种格式。

http://server/site?firstname=&lastname=Daniels

这显然是空字符串""

【讨论】:

  • 谢谢!我没有考虑为第二种情况返回 true 。你有一个显示它是标准的参考吗?
  • 由于这些功能都没有标准化,所以几乎没有参考。当然你可以看看流行的 js 库中的 URL-parsing-functions 的文档。
  • 将此标记为答案,我真的很喜欢在案例 2 中将参数设置为 true 的想法。但是正如我在更新后的帖子中所说,参考看起来不正确。
猜你喜欢
  • 2016-01-15
  • 1970-01-01
  • 1970-01-01
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
  • 2011-04-03
相关资源
最近更新 更多