与其尝试将值插入 URL,不如做正确的事,让 Ruby 处理可能的特殊字符编码:
require 'uri'
name = 'foo'
number = 1
uri = URI('https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true')
uri.query = URI.encode_www_form(
Hash[
URI.decode_www_form(uri.query)
].merge('name' => name, 'count' => number)
)
puts uri
运行后,输出如下:
https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&name=foo&count=1
虽然您可以在 90% 的情况下使用插值将值放入 URL,但有时您需要包含需要编码的字符,并且当您使用插值时,您的 URL 会生成错误尝试使用它。
URI 类遵循查询编码方式的规范,因此您不会遇到这些问题。
分解它,你可以看到会发生什么:
uri.query
# => "include_entities=true&include_rts=true"
URI.decode_www_form(uri.query)
# => [["include_entities", "true"], ["include_rts", "true"]]
Hash[URI.decode_www_form(uri.query)]
# => {"include_entities"=>"true", "include_rts"=>"true"}
Hash[URI.decode_www_form(uri.query)].merge('name' => name, 'count' => number)
# => {"include_entities"=>"true", "include_rts"=>"true", "name"=>"foo", "count"=>1}
URI.encode_www_form(Hash[URI.decode_www_form(uri.query)].merge('name' => name, 'count' => number))
# => "include_entities=true&include_rts=true&name=foo&count=1"
编辑:
URI:Module (NoMethodError) 的未定义方法 `decode_www_form'
我使用 ruby 1.9
查看Addressable 宝石。它做得非常好,并且比内置的 URI 类具有更多功能:
require 'addressable/uri'
name = 'foo'
number = 1
uri = Addressable::URI.parse('https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true')
uri.query_values = uri.query_values.merge('name' => name, 'count' => number)
puts uri
看起来像:
https://api.twitter.com/1/statuses/user_timeline.json?count=1&include_entities=true&include_rts=true&name=foo