簡體   English   中英

如何在Rails中獲取空格為'%20'而不是'+'的url參數

[英]How to get params for url with whitespace as '%20' instead of '+' in Rails

如果我有這個參數來添加到 URL

params = { name: 'John Key' }

並使用方法to_param

params.to_param
 => "name=John+Key"

關鍵是所使用的服務沒有正確讀取“+”,而是需要“%20”而不是name=John%20Key何時將空格編碼為加號 (+) 或 %20?

有沒有辦法在不使用gsub的情況下用 '%20' 返回參數?

我建議只堅持使用gsub ,也許可以用評論來解釋這種行為的必要性。

雖然您可以通過使用URI.escape解決該問題,但據說它已被棄用,因為它不完全符合 RFC 規范。 請參閱此處了解有關它的精彩文章。

Hash#to_param是一個別名Hash#to_query ,它調用Object#to_query 演示此+%20問題的最簡單示例是:

'John Key'.to_query(:name) # => "name=John+Key"

Object#to_query的實現是:

def to_query(key)
  "#{CGI.escape(key.to_param)}=#{CGI.escape(to_param.to_s)}"
end

因此,我們發現:

CGI.escape("John Key") # => "John+Key"

因此,這就是我引用CGI.escapeURI.escape之間CGI.escape URI.escape

怎么樣

URI.encode 'John Smith'
# => John%20Smith

不是真的。

建議使用: your_params_hash.to_query.gsub("+", "%20")

您是否嘗試過使用uri 例如

require 'uri' URI.escape('John Smith')

這個例子中的結果應該是John%20Smith

從其他帖子中了解到 URI.escape 在技術上已被棄用。 其中h代表散列, k是散列中的鍵,試試這個:

params.keys.inject({}) {|h, k| h[k] = ERB::Util.url_encode(params[k]); h }

擴展朱莉的答案以實現編碼值的字符串而不是散列。

隨着URI.encode的貶值,可以使用ERB::Util.url_encode實現這ERB::Util.url_encode ,但是您只需要對鍵和值對進行編碼,而不是完整的參數,然后將它們連接在一起。


params = { name: 'John Key' }

# not what we want
ERB::Util.url_encode(params) # => "%7B%3Aname%3D%3E%22John%20Key%22%7D"

這是一個(很長)可以工作的命令:

# Construct a new object (a string here) and build our params into it correctly.
# k = key of hash. 
# v = value of hash. 
# a = array created in each_with_object.

params.each_with_object([]) { |(k, v), a| a << [ERB::Util.url_encode(k), ERB::Util.url_encode(v)].join('=') }.join('&')

# => "name=John%20Key"

更多參數:

params = { name: 'John Key', occupation: 'Web Developer!', 'Bad Key' => 'but works' }

params.each_with_object([]) { |(k, v), a| a << [ERB::Util.url_encode(k), ERB::Util.url_encode(v)].join('=') }.join('&')

# => "name=John%20Key&occupation=Web%20Developer%21&Bad%20Key=but%20works"

與 Hash.to_query 相比

params.to_query

# => "Bad+Key=but+works&name=John+Key&occupation=Web+Developer%21"

如果您想要一個沒有上下文的字符串的字面百分比編碼(例如,對於類似於Content-Disposition HTTP 標頭的filename*=...值的RFC 5987編碼),那么使用URI.escape / URI.encode (其別名)將一直是正確的。 在這種情況下, 核心庫文檔的建議替換是錯誤的,因為它們不等效:

  • 轉換為+ ,而不是%20
  • +轉換為%2B ,而不是保留為+

一些關於此的帖子建議使用gsub將字符串恢復為原始字符串,但這要簡單得多:

...切換源代碼以查看它是如何工作的 - 它只是一個沒有上下文的鈍編碼器。 當您知道自己在做什么時,這正是您有時想要的,所以我們希望它不會從標准庫中刪除或棄用。

如果我有時間,我打算向核心庫文檔提交一個補丁,其中列出了三個(而不是兩個)可能的替代方案,並提供有關何時使用每個替代方案的更多信息。 現在,從谷歌關於這一點的大量點擊和大量誤導性答案中可以清楚地看出,社區對現狀感到非常困惑。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM