12

这个网址:

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转义方括号?

4

4 回答 4

21

您可以[使用%5B和逃脱]%5D

您的网址将是:

URL.gsub("[","%5B").gsub("]","%5D")

我不喜欢那个解决方案,但它正在工作。

于 2013-07-27T19:06:59.740 回答
11

encode不会转义括号,因为它们并不特殊——它们在 URI 的路径部分没有特殊含义,因此它们实际上不需要转义。

如果您想转义除“不安全”字符之外的字符,请将第二个 arg 传递给 encode 方法。该 arg 应该是一个正则表达式匹配,或者一个包含您想要编码的每个字符的字符串(包括函数本来已经匹配的字符!)。

于 2012-10-22T15:02:54.217 回答
6

如果可以选择使用第三方 gem,请尝试addressable

require "addressable/uri"

url = Addressable::URI.parse("http://[::1]/path[]").normalize!.to_s
#=> "http://[::1]/path%5B%5D"

注意规范化!方法不仅会转义无效字符,还会对主机名部分执行大小写折叠,对不必要的转义字符等进行取消转义:

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"
于 2016-10-04T09:23:31.340 回答
3

根据新的 IP-v6 语法,可能会有这样的 url:

http://[1080:0:0:0:8:800:200C:417A]/index.html

因此,我们应该只在 url 的 host 部分之后转义 [] :

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
于 2016-02-17T15:12:11.407 回答