URL查询字符串中使用方括号的数组语法有效吗?

URL查询字符串中使用方括号的数组语法有效吗?,url,multidimensional-array,query-string,Url,Multidimensional Array,Query String,在URL查询字符串中使用多维数组synthax是否确实安全/有效 http://example.com?abc[]=123&abc[]=456 它似乎适用于所有浏览器,我一直认为它可以使用,但根据本文中的评论,它不是: 我想听听第二种意见。根据RFC 3986,URL的语法如下: *( pchar / "/" / "?" ) 来自同一RFC的: pchar = unreserved / pct-encoded / sub-delims / ":" / "@" [...

在URL查询字符串中使用多维数组synthax是否确实安全/有效

http://example.com?abc[]=123&abc[]=456
它似乎适用于所有浏览器,我一直认为它可以使用,但根据本文中的评论,它不是:


我想听听第二种意见。

根据RFC 3986,URL的语法如下:

*( pchar / "/" / "?" )
来自同一RFC的:

pchar         = unreserved / pct-encoded / sub-delims / ":" / "@"
[...]
pct-encoded   = "%" HEXDIG HEXDIG

unreserved    = ALPHA / DIGIT / "-" / "." / "_" / "~"
[...]    
sub-delims    = "!" / "$" / "&" / "'" / "(" / ")"
             / "*" / "+" / "," / ";" / "="
我对这一点的解释是,任何不是:

 ALPHA / DIGIT / "-" / "." / "_" / "~" / 
     "!" / "$" / "&" / "'" / "(" / ")" / 
     "*" / "+" / "," / ";" / "=" / ":" / "@"

…应为pct编码,即百分比编码。因此,
[
]
应该按照RFC 3986进行百分比编码。

当我必须传递数组时,我总是想进行这种查询,但我避开了它。原因是:

  • 未清除RFC中定义的
  • 不同的语言可能会有不同的解释
您有几个选项可以传递数组:

  • 对数组的字符串表示进行编码(JSON可能是?)
  • 有“val1=blah&val2=blah&…”之类的参数

如果您对所使用的语言有把握,您可以(安全地)选择您拥有的查询字符串类型(只需对其进行%-encode
[]
编码)。

我的理解是,方括号无论如何都不是头等公民。以下是报价:

其他字符不安全,因为网关和其他传输 已知代理有时会修改这些字符。这些 字符为“{”、“}”、“|”、“\”、“^”、“~”、“[”、“]”和“`”


答案并不简单

以下内容摘自RFC 3986第3.2.2节:

由Internet协议文本地址标识的主机,版本6
[RFC3513]或更高版本通过包含IP文本来区分
在方括号内(“[”和“]”)。这是唯一一个
URI语法中允许使用方括号字符

这似乎通过断然声明URI中其他任何地方都不允许方括号来回答问题。但方括号字符和百分比编码方括号字符之间存在差异

以下摘自RFC 3986第3节开头部分:

  • 语法组件

    通用URI语法由一个层次序列组成
    被称为方案、权限、路径、查询和
    碎片

    URI=方案“:“hier部分[”?“查询][“#”片段]

  • 因此,“查询”是“URI”的一个组件

    以下内容摘自RFC 3986第2.2节:

    2.2。保留字符

    URI包括由分隔的组件和子组件
    “保留”集中的字符。这些字符称为
    “保留”,因为
    通用语法,通过每个特定于方案的语法,或通过
    URI的解引用算法的特定于实现的语法。
    如果URI组件的数据与保留的冲突
    字符用作分隔符,则冲突数据必须
    必须在URI形成之前进行百分比编码

      reserved    = gen-delims / sub-delims
    
      gen-delims  = ":" / "/" / "?" / "#" / "[" / "]" / "@"
    
      sub-delims  = "!" / "$" / "&" / "'" / "(" / ")"
                  / "*" / "+" / "," / ";" / "="
    
    因此,方括号可能会出现在查询字符串中,但前提是它们是百分比编码的。除非没有,否则将在第2.2节中进一步解释:

    产生URI的应用程序应该对数据八位字节进行百分比编码
    与保留集中的字符相对应,除非这些字符
    URI方案特别允许以该方式表示数据
    组成部分。如果在URI组件中找到保留字符,并且
    该角色没有已知的定界角色,那么它必须是
    解释为表示与之对应的数据八位字节
    字符的US-ASCII编码

    因此,由于方括号仅允许在“主机”子组件中使用,因此它们“应该”在其他组件和子组件中使用百分比编码,在这种情况下,在“查询”组件中使用百分比编码,除非RFC 3986明确允许未编码方括号表示查询组件中的数据,而查询组件中不允许

    但是,如果一个“URI生成应用程序”在查询中未对方括号进行编码而未能完成它“应该”做的事情,那么URI的读取器就不能完全拒绝URI。相反,方括号将被视为属于查询组件的数据,因为它们在该组件中不用作分隔符


    这就是为什么,例如,当PHP接受未编码和百分比编码的方括号作为查询字符串中的有效字符,甚至为它们指定一个特殊用途时,这并不违反RFC 3986。然而,试图利用这一漏洞而不使用百分比编码方括号的作者似乎违反了RFC 3986。

    大卫·N·杰弗里安的答案太棒了。我只想添加一些更新和实用说明:

  • 多年来,在向服务器提交请求时,每个浏览器都在查询字符串中保留了未编码的方括号。(来源:)。因此,我认为网络的很大一部分已经开始依赖这种行为,这使得它极不可能改变

  • 我对WHATWG URL标准的理解是,它将这种不在查询字符串中编码的行为编码为
    [
    ]
    ,至少在web上可以被视为取代了RFC 3986


  • 编辑:根据评论和其他答案,对WHATWG URL标准更正确的解读是,未编码的
    [
    /
    ]
    是无效的,但在接收/解析时也应该被容忍,并且,一旦以这种方式解析,甚至应该在不编码的情况下重新序列化。

    我非常想评论一下,但是没有足够的声誉去做这件事

    我不确定相关部分