在使用OpenURI的open(url)
方法之前,我该如何对URL进行编码或转义?
我们正在使用OpenURI打开远程URL并返回XML:
getresult = open(url).read
问题在于URL包含一些用户输入的文本,其中包含空格和其他字符,包括"+", "&", "?",等等,因此我们需要安全地转义URL。我看到了很多使用Net::HTTP的例子,但没有发现任何关于OpenURI的。
我们还需要能够取消转义接收到的类似字符串,因此我们需要对应的函数。
请勿使用 URI.escape
,因为它已在1.9中被弃用。
Rails的Active Support添加了Hash#to_query
:
{foo: 'asd asdf', bar: '"<#$dfs'}.to_query
# => "bar=%22%3C%23%24dfs&foo=asd+asdf"
此外,正如您所看到的,它始终尝试以相同的方式对查询参数进行排序,这对于HTTP缓存是有益的。
使用 Ruby 标准库来拯救:
require 'uri'
user_text = URI.escape(user_text)
url = "http://example.com/#{user_text}"
result = open(url).read
请查看URI::Escape模块的文档。该模块也有一个方法来执行相反的操作(unescape
)。
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"}]
CGI::escape
可以正确地执行所有操作,除了+
,你可能只需对结果进行gsub
。但是,如果你使用的是**ruby 1.9+**,那么似乎可以使用函数URI.encode_www_form_component
代替。 - Arsen7query_values=
方法时会为您处理编码。