如何从 Java 和 Ruby 中以相同的方式转义保留的 URL 字符



我有两个客户端,一个用Java编写,另一个用Ruby编写,需要从字符串中转义保留的URL字符。我遇到的问题是我找不到在两个平台上进行完全相同编码的库。输出需要完全相同,以便稍后可以比较转义字符串的相等性。

为什么要比较转义格式的 URL 字符串?即使 URL 的转义方式可能不同,您也可以取消转义它们并比较生成的字符串值。两个平台的未转义值应相同。

问题是,您无法保证生成的 URL 是一致的。查询参数的排序方式可以不同,这将中断将 URL 作为字符串进行比较的所有尝试。

相反,您必须将 URL 分解为它们的组件。URI规范得到了很好的遵循,我们可以做到这一点并检索各个部分并进行比较。

例如:

require 'uri'
URL1 = 'http://www.example.com?foo=1&bar=2'
URL2 = 'http://www.Example.com?bar=2&foo=1'
URL1 == URL2 # => false
url1 = URI.parse(URL1)
url2 = URI.parse(URL2)
(url1.host.downcase == url2.host.downcase) && (URI.decode_www_form(url1.query).sort == URI.decode_www_form(url2.query).sort)
# => true

尝试将URL1URL2作为字符串进行比较,它将失败。尝试将查询作为字符串进行比较,它将失败。对主机进行不区分大小写的比较,并对查询组件进行排序,以便它们被规范化,并且您有合理的机会比较事物以查看它们是否匹配。

如果您知道接收查询的主机不区分大小写,则可以将其缩短一点:

url1 = URI.parse(URL1.downcase)
url2 = URI.parse(URL2.downcase)
(url1.host == url2.host) && (URI.decode_www_form(url1.query).sort == URI.decode_www_form(url2.query).sort)
# => true

我遇到过期望在查询中使用区分大小写的参数以及与位置相关的参数的主机,因此将所有内容折叠为小写可能不适用于特定 URL,但对于测试相等性,它应该没问题。

最新更新