Techioz Blog

Addressable の encode_www_form_component に相当する URI

概要

Addressable::URI の URI.encode_www_form_component に相当するメソッドは何ですか?

解決策

最も近い方法は、#encode_component メソッドを使用することです。 Addressable は完全なパーセント モードを使用し、スペースを + ではなく %20 に置き換えることに注意してください。

Addressable::URI.encode_component('a decoded string with [email protected]', Addressable::URI::CharacterClasses::UNRESERVED)
# => "a%20decoded%20string%20with%20email%40example.com"

URI.encode_www_form_component('a decoded string with [email protected]')
# => "a+decoded+string+with+email%40example.com"

キー/値パラメーターの完全なセットをエンコードする 2 つのメソッドを比較すると、どちらもより類似した動作をすることがわかります。

[15] pry(main)> Addressable::URI.form_encode([["q", "a decoded string with [email protected]"]])
=> "q=a+decoded+string+with+email%40example.com"
[16] pry(main)> URI.encode_www_form([["q", "a decoded string with [email protected]"]])
=> "q=a+decoded+string+with+email%40example.com"

実際にテストしてみて驚きました。そこで、Addressable のソース コードを詳しく調べたところ、form_encode メソッドが %20 を + に明示的に置き換えていることがわかりました。

escaped_form_values = form_values.map do |(key, value)|
  # Line breaks are CRLF pairs
  [
    self.encode_component(
      key.gsub(/(\r\n|\n|\r)/, "\r\n"),
      CharacterClasses::UNRESERVED
    ).gsub("%20", "+"),
    self.encode_component(
      value.gsub(/(\r\n|\n|\r)/, "\r\n"),
      CharacterClasses::UNRESERVED
    ).gsub("%20", "+")
  ]
end

したがって、オプションは次のとおりです。