此网址:
http://gawker.com/5953728/if-alison-brie-and-gillian-jacobs-pin-up-special-doesnt-get-community-back-on-the-air-nothing-will-[nsfw]
应该是:
http://gawker.com/5953728/if-alison-brie-and-gillian-jacobs-pin-up-special-doesnt-get-community-back-on-the-air-nothing-will-%5Bnsfw%5D
但是当我将第一个传递给URI.encode
时,它不会逃避方括号。我也试过了CGI.escape
,但也逃脱了所有'/'。
我应该使用什么来正确转义URL?为什么URI.encode
没有方括号?
答案 0 :(得分:10)
encode
不会转义括号,因为它们并不特殊 - 它们在URI的路径部分没有特殊含义,因此它们实际上不需要转义。
如果你想要转义除“不安全”之外的字符,请将第二个arg传递给encode方法。那个arg应该是一个正则表达式匹配,或者是一个包含你想要编码的每个字符的字符串(包括字符,否则该函数已经匹配!)。
答案 1 :(得分:3)
如果选择使用第三方gem,请尝试addressable。
require "addressable/uri"
url = Addressable::URI.parse("http://[::1]/path[]").normalize!.to_s
#=> "http://[::1]/path%5B%5D"
注意规范化!方法不仅会转义无效字符,还会在主机名部分执行casefolding,对不必要的转义字符进行转义等等:
uri = Addressable::URI.parse("http://Example.ORG/path[]?query[]=%2F").normalize!
url = uri.to_s #=> "http://example.org/path%5B%5D?query%5B%5D=/"
因此,如果您只想标准化路径部分,请执行以下操作:
uri = Addressable::URI.parse("http://Example.ORG/path[]?query[]=%2F")
uri.path = uri.normalized_path
url = uri.to_s #=> "http://Example.ORG/path%5B%5D?query[]=%2F"
答案 2 :(得分:1)
根据new IP-v6 syntax,可能会有这样的网址:
http://[1080:0:0:0:8:800:200C:417A]/index.html
因此我们应该在url的主机部分之后逃避[]:
if url =~ %r{\[|\]}
protocol, host, path = url.split(%r{/+}, 3)
path = path.gsub('[', '%5B').gsub(']', '%5D') # Or URI.escape(path, /[^\-_.!~*'()a-zA-Z\d;\/?:@&%=+$,]/)
url = "#{protocol}//#{host}/#{path}"
end