EscapeUriString 和 EscapeDataString 有什么区别?

11 浏览
0 Comments

EscapeUriString 和 EscapeDataString 有什么区别?

如果只涉及到URL编码,我应该使用EscapeUriString吗?

admin 更改状态以发布 2023年5月21日
0
0 Comments

始终使用EscapeDataString(有关详细信息,请参见下面的Livven的答案

编辑:删除关于如何区分这两种编码方式的失效链接

0
0 Comments

我发现现有的答案都不令人满意,所以我决定深入挖掘来解决这个问题。令人惊讶的是,答案非常简单:

几乎没有使用Uri.EscapeUriString的有效理由。如果您需要对字符串进行百分比编码,请始终使用Uri.EscapeDataString。*

*请参见最后一段以了解有效的用例。

为什么呢?根据文档

使用EscapeUriString方法将未转义的URI字符串准备好,以成为Uri构造函数的参数。

这并没有什么意义。根据RFC 2396

URI始终处于“转义”形式,因为对已完成的URI进行转义或取消转义可能会更改其语义。

虽然引用的RFC已被RFC 3986所废除,但这一点仍然成立。让我们通过查看一些具体的示例来验证它:

  1. 您有一个简单的URI,例如:

     http://example.org/
    

Uri.EscapeUriString不会改变它。

  1. 您决定手动编辑查询字符串而不考虑转义:

     http://example.org/?key=two words
    

Uri.EscapeUriString将(正确地)为您转义空格:

    http://example.org/?key=two%20words

  1. 您决定再次手动编辑查询字符串:

     http://example.org/?parameter=father&son
    

但是,此字符串不会被Uri.EscapeUriString更改,因为它认为“&”表示另一个键值对的开始。这可能是您想要的,也可能不是您想要的。

  1. 您决定实际上希望key参数为father&son,因此您手动修复了先前的URL并转义了“&”:

     http://example.org/?parameter=father%26son
    

然而,Uri.EscapeUriString也会转义百分比字符,导致双重编码:

    http://example.org/?parameter=father%2526son

正如您所看到的,使用Uri.EscapeUriString的目的使得无法使用&作为查询字符串中键或值的一部分,而不是作为多个键值对之间的分隔符。

这是因为,为了使其适用于转义完整的URI,它忽略保留字符并仅转义既不保留也不未保留的字符,这与文档相反。这样,您不会得到像http%3A%2F%2Fexample.org%2F这样的内容,但您会遇到上面所述的问题。


最终,如果您的 URI 是有效的,则不需要进行转义即可作为参数传递给 Uri 构造函数,如果不是,则调用 Uri.EscapeUriString 也不是一个神奇的解决办法。实际上,在许多情况下甚至在大多数情况下,它都可以工作,但它绝不可靠。

您应该始终通过收集键值对并进行百分比编码,然后使用必要的分隔符进行拼接来构建您的 URL 和查询字符串。您可以使用 Uri.EscapeDataString 来实现此目的,但不要使用 Uri.EscapeUriString,因为它不会转义保留字符,如上所述。

只有在无法进行上述操作时,例如处理用户提供的 URI 时,才有必要使用 Uri.EscapeUriString 作为最后的选择。但是,前面提到的注意事项仍然适用-如果用户提供的 URI 不明确,则结果可能不理想。

0