在URL中添加参数

45

1
我们需要更多的信息才能提供帮助,例如代码。根据目前的情况,我建议使用 "uri + 'wmode=opaque'",这将给您正确的字符串。您正在使用 net/http 还是其他库? - Kassym Dorsel
我想确保它正确连接(这是用户输入)。注意:'http://www.youtube.com/watch' + 'wmode=opaque' 应该变成 'http://www.youtube.com/watch?wmode=opaque'。 - manuels
如果您的参数是一个Hash,请尝试使用to_query。它是ActiveSupport的一部分,所以您可能还需要引入它。但它对我们非常有用。 - Joshua Pinter
5个回答

71
require 'uri'

uri =  URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
uri.query = [uri.query, "wmode=opaque"].compact.join('&') 
puts uri.to_s

#edit Since 1.9.2 there are methods added to the URI module

uri =  URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
new_query_ar = URI.decode_www_form(String(uri.query)) << ["wmode", "opaque"]
uri.query = URI.encode_www_form(new_query_ar)
puts uri.to_s

(调用 String 确保在原始 URI 没有查询字符串的情况下也可以使用)


3
如果URL没有参数,uri.query返回nil,并且URI.decode_www_form(nil)会出错。 - fguillen
如果遇到 nil 问题,请使用以下程序相关内容进行翻译:new_query_ar = URI.decode_www_form(uri.query || []) << ["wmode", "opaque"] - luxerama
3
注意:decode方法需要一个字符串而不是数组,因此代码将空字符串作为参数传递给了URI.query。然后向这个数组中加入了["wmode", "opaque"]这两个元素。new_query_ar = URI.decode_www_form(uri.query || '') << ["wmode", "opaque"] - Dane Lowe
8
这个答案已经过时了。请使用URI.encode_www_form({wmode: "opaque"})代替。 - Cameron A. Ellis

24

随着多年来Ruby的发展,不同版本的答案也有所不同。

1.9.2版本之后

Ruby 1.9.2版本增加了decode_www_formencode_www_form函数到URI模块中,使得参数编码更加容易。

require 'uri'

uri = URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
new_query_ar = URI.decode_www_form(uri.query || '') << ["wmode", "opaque"]
uri.query = URI.encode_www_form(new_query_ar)
puts uri.to_s

解释

URI.decode_www_form将一个查询参数字符串(uri.query)分解成一组嵌套的参数数组([["v", "og9B3BEnBHo"]])。

uri.query || ''提供了uri的查询字符串,如果不存在则提供一个空字符串。这可以防止decode_www_form遇到nil时出现错误。

<< ["wmode", "opaque"]添加另一个元素到查询参数数组中。您可以通过进一步扩展new_query_ar来添加更多元素:new_query_ar << ["fullscreen", "1"]

URI.encode_www_form将嵌套的新查询参数数组编码为字符串。

1.9.2之前

require 'uri'

uri = URI.parse("http://www.youtube.com/watch?v=og9B3BEnBHo")
uri.query = [uri.query, "wmode=opaque"].compact.join('&') 
puts uri.to_s

解释

[uri.query, "wmode=opaque"] 是一个包含所有最终查询参数的数组。您可以通过扩展数组来添加更多参数:[uri.query, "wmode=opaque", "fullscreen=1"],或者通过将新的参数添加到最后一个元素中:"wmode=opaque&fullscreen=1"

compact 从数组中删除 nil 元素,因此如果没有现有的查询参数,则它会删除 uri.query

最后,join 将它们连接成一个查询字符串。


10

由于您可能有多个要添加而不仅仅是一个查询参数,因此这里提供了一种版本,通过简单地传递哈希值,可以让您附加任意数量的参数...另外,似乎使用哈希表作为传递params的方式更自然,即使您只添加一个参数。

  require 'uri'
  def add_params(url, params = {})
    uri = URI(url)
    params    = Hash[URI.decode_www_form(uri.query || '')].merge(params)
    uri.query =      URI.encode_www_form(params)
    uri.to_s
  end

示例:

pry(main)> helper.add_params("http://example.com", b: 2)
=> "http://example.com?b=2"

pry(main)> helper.add_params("http://example.com?a=1", b: 2, c: 3)
=> "http://example.com?a=1&b=2&c=3"

pry(main)> helper.add_params("http://www.youtube.com/watch?v=og9B3BEnBHo", wmode: 'opaque')
=> "http://www.youtube.com/watch?v=og9B3BEnBHo&wmode=opaque"

9
另一个选项是使用Addressable gem

https://github.com/sporkmonger/addressable

一旦您在项目中引入Addressable,您需要做的只有:
url = Addressable::URI.parse('http://www.youtube.com/watch?v=og9B3BEnBHo')
url.query_values = (url.query_values || {}).merge(wmode:"opaque")

与可寻址 HTTPS 相关的问题 https://github.com/sporkmonger/addressable/issues/334 - brauliobo

0
在最近版本的URI模块中,您可以简单地执行以下操作:
original_uri = 'http://www.youtube.com/watch?v=og9B3BEnBHo'
append_params = { 'wmode': 'opaque' }

uri = URI.parse(original_uri)
params = URI.decode_www_form(uri.query || '') + append_params.to_a
uri.query = URI.encode_www_form(params)
puts uri.to_s

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接