什么是有效的,什么不在URI查询中?

背景(进一步的问题)

我一直在谷歌searchRFC和SO试图破解这个问题,但我仍然没有杰克。

所以我想我们只是投票“最好”的答案,就是这样,或?

基本上归结到这一点。

3.4。 查询组件

查询组件是由资源解释的一串信息。

query = *uric

在查询组件中,字符“;”,“/”,“?”,“:”,“@”,“&”,“=”,“+”,“,”和“$”被保留。

第一件令我难以置信的事就是* uric就是这样定义的

uric = reserved | unreserved | escaped

reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","

但是,这样的说法可以稍微澄清一些

上面的“保留”语法类是指URI内允许使用的那些字符,但在通用URI语法的特定组件中可能不允许使用这些字符。 它们被用作第3节中描述的组件的分隔符。

“保留”集中的字符在所有上下文中都不保留。 在任何给定的URI组件中实际保留的字符集由该组件定义。 一般来说,如果URI的语义由于其US-ASCII编码而被replace,则字符被保留。

这最后的摘录感觉有些落后,但它清楚地表明,保留的字符集取决于上下文。 然而,3.4声明所有的保留字符都是保留在一个查询组件中的,但是,唯一会改变这里的语义的是逃避问号(?),因为URI没有定义查询string的概念。

在这一点上,我完全放弃了RFC,但发现RFC 1738特别有趣。

一个HTTP URL的格式如下:

http://<host>:<port>/<path>?<searchpart>

在<path>和<searchpart>组件中,“/”,“;”,“?” 保留。 可以在HTTP中使用“/”字符来指定分层结构。

我至less对于RFC 1738取代RFC 2396的HTTP URL进行了解释。因为URI查询没有查询string的概念,所以保留的解释并不真的允许我定义查询string,因为我习惯于现在做。

这一切都开始时,我想与其他资源的请求一起传递一个数字列表。 我没有想太多,只是通过它作为逗号分隔值。 令我吃惊的是,这个逗号已经逃脱了。 查询page.html?q=1,2,3编码转换成page.html?q=1%2C2%2C3它的工作原理,但它是丑陋的,没想到它。 那时候我开始通过RFC。

我的第一个问题很简单,编码逗号真的有必要吗?

根据RFC 2396,我的回答是:根据RFC 1738:没有

后来我发现有关请求之间的列表通过相关的职位。 csv方法准备好了。 这显示出来,(以前没有见过)。

 page.html?q=1;q=2;q=3 

我的第二个问题是,这是一个有效的url?

我的答案,根据RFC 2396:不,根据RFC 1738:否(;保留)

只要是数字,我就没有任何问题传递CSV,但是如果逗号突然被别的东西需要,你会遇到不得不对数值进行编码和解码的风险。 无论如何,我尝试了与ASP.NET的分号查询string的事情,结果不是我所期望的。

 Default.aspx?a=1;a=2&b=1&a=3 Request.QueryString["a"] = "1;a=2,3" Request.QueryString["b"] = "1" 

我没有看到这与csv方法有什么不同,因为当我要求“a”时,我得到一个带有逗号的string。 ASP.NET当然不是一个参考实现,但它还没有让我失望。

但最重要的是 – 我的第三个问题 – 这是什么规格? 你会做什么或者做什么呢?

在通用URL组件中保留一个字符并不意味着它必须在组件内或组件内的数据内出现。 该字符还必须在通用或特定于计划的语法内定义为分隔符,并且该字符的外观必须在数据内。

通用URI的当前标准是RFC 3986 ,它有这样的说法:

2.2。 保留字符

URI包含由“保留”集中的字符分隔的组件和子组件。 这些字符被称为“保留”,因为它们可能(或可能不)被通用语法,每个scheme特定语法或URI的解引用algorithm的特定于实现的语法定义为分隔符。 如果URI组件的数据与保留字符作为分隔符 [强调添加] 的目的冲突,则在URI形成之前,冲突的数据必须进行百分比编码。

  reserved = gen-delims / sub-delims

    gen-delims =“:”/“/”/“?”  /“#”/“[”/“]”/“@”

    sub-delims =“!”  /“$”/“&”/“'”/“(”/“)”
                /“*”/“+”/“,”/“;”  /“=” 

3.3。 path组件

[…]

  pchar = unreserved / pct-encoded / sub-delims /“:”/“@” 

[…]

3.4查询组件

[…]

  query = *(pchar /“/”/“?”) 

因此,在查询string中明确允许逗号,如果特定scheme将其定义为分隔符,则只需要在数据中转义。 HTTPscheme在查询string中不使用逗号或分号作为分隔符,因此不需要转义。 浏览器是否遵循这个标准是另一回事。

使用CSV应该可以很好地处理string数据,您只需遵循标准的CSV约定,并引用数据或用反斜杠转义逗号。

至于RFC 2396,它也允许在HTTP查询string中使用逗号:

2.2。 保留字符

许多URI包含由某些特殊字符组成或由其定界的组件。 这些字符被称为“保留”,因为它们在URI组件中的使用仅限于其保留的用途。 如果URI组件的数据与保留目的冲突,那么冲突的数据必须在形成URI之前转义。

由于逗号在HTTPscheme下没有保留的用途,所以不需要在数据中转义。 关于保留字符的§2.3的注释是那些在百分比编码时只改变语义的应用。 字符可以百分比编码而不改变具体scheme的语义,但仍然被保留。

只需使用?q=1+2+3

我在这里回答第四个问题:)没有问,但所有的开始:我如何通过数字列表的逗号分隔值? 对我来说,最好的办法就是将它们以空格分开,其中空格将以urlforms编码为+ 。 效果很好,只要你知道列表中的值不包含空格(数字往往不会)。

要回答查询string中的有效内容,我在检查时检查了哪些特殊字符被chromereplace:

 Space -> %20 ! -> ! " -> %22 # -> removed, marks the end of the query string % -> % & -> & ' -> %27 ( -> ( ) -> ) * -> * + -> + (this usually means blank when received at the server, so encode if necessary) , -> , - -> - . -> . / -> / : -> : ; -> ; < -> %3C = -> = > -> %3E ? -> ? @ -> @ [ -> [ \ -> \ ] -> ] ^ -> ^ _ -> _ ` -> ` { -> { | -> | } -> } ~ -> ~ Extended ASCII (like °) -> Every character from this set is encoded 

注意:这可能并不意味着当你为链接生成URI时,你不应该转义那些没有被replace的字符。 例如,由于兼容性问题,通常build议不要在URI中使用~ ,但它仍然是一个有效的字符。

另一个例子是有效的加号,但是当服务器收到它作为请求的一部分时通常被视为编码空白。 因此,即使它的目的是表示加号而不是空格,它也应该被编码。

因此,要回答什么应该编码:无效的字符和字符,你想字面上处理,但有一个特殊的含义,或可以在服务器端造成麻烦。

?page.html中Q = 1; Q = 2; q = 3的

这是一个有效的url?

是。 The ; 是保留的,但不是由RFC。 定义这个组件的上下文是application/x-www-form-urlencoded媒体types的定义,它是HTML标准的一部分(第17.13.4.1节)。 特别是隐藏在B.2.2节中的偷偷摸摸的笔记:

我们推荐HTTP服务器实现者,特别是CGI实现者支持使用“;” 代替“&”来节省作者以这种方式逃避“&”字符的麻烦。

不幸的是,许多stream行的服务器端脚本框架,包括ASP.NET,都不支持这种用法。

我想指出的是, page.html?q=1&q=2&q=3也是一个有效的url。 这是在查询string中expression数组的一种完全合法的方式。 您的服务器技术将决定如何呈现。

在经典的ASP中,你检查Response.QueryString("q").Count并且然后使用Response.QueryString("q")(0) (和(1)和(2))。

请注意,您在ASP.NET中也看到了这一点(我认为这不是有意的,但看起来):

 Default.aspx?a=1;a=2&b=1&a=3 Request.QueryString["a"] = "1;a=2,3" Request.QueryString["b"] = "1" 

请注意,分号被忽略,所以你有a定义两次,你得到它的价值两次,用逗号分隔。 使用所有&符号Default.aspx?a=1&a=2&b=1&a=3将产生a “1,2,3”。 但是我确定有一个方法来获取每个单独的元素,以防元素本身包含逗号。 它只是非索引QueryString的默认属性,它们将子值与逗号分隔符连接在一起。

我遇到过同样的问题。 超链接的URL是第三方URL,并且期望以page.html?q=1,2,3格式显示参数列表,并且URL page.html?q=1%2C2%2C3不起作用。 我能够得到它使用JavaScript的工作。 可能不是最好的方法,但可以检查出解决scheme,如果它可以帮助任何人。

如果您将ENCODED字符发送到FLASH / SWF文件,那么您应该两次ONCODE字符! (由于Flashparsing器)