您必须考虑的主要事情是,在编写完整的 URL之前,您必须分别转义键和值。
所有获取完整 URL 并在之后尝试对其进行转义的方法都被破坏了,因为它们无法判断是否有任何字符&
或=
字符应该是分隔符,或者可能是值的一部分(或键的一部分)。
CGI 库似乎做得很好,除了空格字符,传统上编码为+
,现在应该编码为%20
. 但这是一个简单的解决方法。
请考虑以下几点:
require 'cgi'
def encode_component(s)
# The space-encoding is a problem:
CGI.escape(s).gsub('+','%20')
end
def url_with_params(path, args = {})
return path if args.empty?
path + "?" + args.map do |k,v|
"#{encode_component(k.to_s)}=#{encode_component(v.to_s)}"
end.join("&")
end
def params_from_url(url)
path,query = url.split('?',2)
return [path,{}] unless query
q = query.split('&').inject({}) do |memo,p|
k,v = p.split('=',2)
memo[CGI.unescape(k)] = CGI.unescape(v)
memo
end
return [path, q]
end
u = url_with_params( "http://example.com",
"x[1]" => "& ?=/",
"2+2=4" => "true" )
# "http://example.com?x%5B1%5D=%26%20%3F%3D%2F&2%2B2%3D4=true"
params_from_url(u)
# ["http://example.com", {"x[1]"=>"& ?=/", "2+2=4"=>"true"}]