def build(args)
# these things are not used by my application, so they're unnecessary
userinfo, port, registry, opaque = nil
scheme = args[:scheme]
host = args[:host]
path = encoded_path(args[:path])
query = args[:query]
fragment = args[:fragment]
uri = URI::Generic.new(scheme, userinfo, host, port, registry, path, opaque, query, fragment)
new(uri)
end
5条答案
按热度按时间t9aqgxwy1#
没有真实的的方法,您只需要跟踪字符串是否已经进行了URI转义。如果你有一个字符串,你不知道它是否已经URI转义,没有好的解决方案。
一般来说,你应该在代码中的一个点上进行编码。在内存中,所有的字符串通常不应该是URI转义的。在从URI解析组件之后,应该立即取消转义组件。在构造URI时,只在构造完整URI时对它们进行转义/编码。
如果你有一个字符串,但不知道它是否被编码,那你就不走运了;您需要跟踪,理想情况下,通过确保编码发生在清晰的系统边界上。
wfveoks02#
更新:
我更新我的帖子,因为URI.encode/decode在较新版本的Ruby中被弃用。
我认为创建一个 Package 器URI类来处理这个问题是值得的,这样您就不必每次都这样做。您甚至可以做一些聪明的事情,比如假设URI被正确解析,如果有解析错误,则尝试将其完全转义并重新转义。
虽然这确实有效,但在理想情况下,您将解析URI,并假设它们已正确编码,并且在构建URI时确保组件已正确编码。这就是为什么在构建URI对象时,我更喜欢单独转义每个组件:
其中
encoded_path
只对a-zA-Z\d_\.-~\/
的路径字符集进行%编码。当使用URI对象时,通常在字符串化之前修改querystring,所以我选择将querystring表示为哈希,当在uri对象上调用
to_s
时,每个值都单独用CGI.escape
进行%编码。这确保了像嵌套的URI对象作为queyrstring值这样的东西被正确地转义。您可以从IETF网站阅读有关RFC 3986的%编码和保留字符的更多信息。
尽管如此,有时仍然不可能知道URI是否% encoded
原文:
在编码之前先解码URI有什么问题吗?为了编码的安全性,你牺牲了一点性能:
它的速度比简单编码的两倍要慢一点,但它比
Addressable
等替代方案快得多。6bc51xsx3#
用户jordan对此问题有一个重复的部分有效答案
(Ruby - how to encode URL without re-encoding already encoded characters)。
URI.escape
在所有情况下都可以按照您想要的方式工作,除非字符已经编码。考虑到这一点,我们可以使用URI.encode
的结果并使用String#gsub
来“取消编码”这些字符。下面的正则表达式查找
%25
(编码的%
),后跟两个十六进制数字,例如%252f
返回到%2f
:这是一个有点笨拙,但它适用于所有的问题情况下,我有。更好的是,它是幂等的:
8nuwlpux4#
Addressable gem通常具有URI库中缺少的方法。在这种情况下,Addressable::URI的
normalized_encode
方法可以实现以下功能:参考资料:http://www.rubydoc.info/gems/addressable/2.3.5/Addressable/URI#normalized_encode-class_method
9wbgstp75#
我不确定OpenURI中是否包含一个方法来实现这一点,因此只需与ternary运算符进行比较。
它易于阅读和简单。
可能还有其他方法,包括检查字符串中的某些字符等。但我认为为了保持事情的简单性和可读性,这是一个体面的解决方案。