Ruby-如何在不重新编码已编码字符的情况下编码URL

Kul*_*gar 3 ruby ruby-on-rails

我有一个简单的问题:用户可以通过特定输入在我的网站中以特定形式发布网址。我想对发布的网址进行编码,因为有时用户会发送带有奇怪和/或非ASCII字符的网址(例如éàç...)。例如:https://www.example.com/url-déjà-vu

因此,我尝试使用URI.escape('https://www.example.com/url-déjà-vu')哪种方法有效,但是如果您具有以下网址,URI.escape('https://somesite.com/page?stuff=stuff&%20')则会得到: => "https://somesite.com/page?stuff=stuff&%2520"

%字符已编码,不应如此,因为%20已经是编码字符。然后我以为我可以这样做:

URI.escape(URI.decode('https://somesite.com/page?stuff=stuff&%20'))
=> "https://somesite.com/page?stuff=stuff&%20"
Run Code Online (Sandbox Code Playgroud)

但是,如果您的网址中带有“ /”编码,则存在问题,例如:

URI.escape(URI.decode('http://example.com/a%2fb'))
=> "http://example.com/a/b"
Run Code Online (Sandbox Code Playgroud)

“ /”应保持编码状态。

所以...全部放在一起:我想对用户发布的url进行编码,但在ruby中将已经编码的字符保留不变。知道我该怎么做而不会头疼吗?

谢谢 :)

Jor*_*ing 5

我想不出一点点方法就可以做到这一点。因此,我提出了一点建议。

URI.escape在所有情况下似乎都可以按照您想要的方式工作,除非已经对字符进行了编码。考虑到这一点,我们可以采用的结果URI.encodeString#gsub仅对那些字符进行“非编码”。

下面的正则表达式查找%25(一个编码的%)后跟两个十六进制数字,例如,将其%252f转换为%2f

require "uri"

DOUBLE_ESCAPED_EXPR = /%25([0-9a-f]{2})/i

def escape_uri(uri)
  URI.encode(uri).gsub(DOUBLE_ESCAPED_EXPR, '%\1')
end

puts escape_uri("https://www.example.com/url-déjà-vu")
# => https://www.example.com/url-d%C3%A9j%C3%A0-vu

puts escape_uri("https://somesite.com/page?stuff=stuff&%20")
# => https://somesite.com/page?stuff=stuff&%20

puts escape_uri("http://example.com/a%2fb")
# => http://example.com/a%2fb
Run Code Online (Sandbox Code Playgroud)

我不保证这是万无一失的,但希望能有所帮助。