在做签名时,发现了一个问题:Rails
中Hash#to_query
的方法不只是简单的将hash
拼接成query
形式,还会encode
query
串,如果不知道这点很容易就会做出再次encode
的蠢事了(比如我)。
还有一点,js
的encodeURIComponent
的方法将空格转义为"%20",但是rails
的Hash#to_query
将空格转义为"+",这样就会导致最终签名不一致。这是rails
的to_query
处理的问题。
目前除了把+
直接替换为%20
外,还没有找到其他更好的方法。
ruby:
h = {a: 1, b: "a b"}
h.to_query.gsub("+", "%20") # a=1&b=a%20b
NOTE: 请确保前端是分别对键和值使用 encodeURIComponent 进行 encode 后再拼接成 query 的,如果是先拼接成 query 再encode将会导致 = 号也会被转义,而 ruby 的 to_query 是不转义 = 号的。
还有一件事,js
还有一个叫encodeURI
的方法,使用这个方法encode
虽然不会转义=
号,但是也不会转义主机名部分的内容:
let query_str = "id=1&url=https://www.mini-geek.com"
console.log(encodeURI(query_str))
// id=1&url=https://www.mini-geek.com
console.log(encodeURIComponent(query_str))
// id%3D1%26url%3Dhttps%3A%2F%2Fwww.mini-geek.com
顺便放上ruby
部分作为比较吧
h = {
id: 1,
url: "https://www.mini-geek.com"
}
h.to_query # id=1&url=https%3A%2F%2Fwww.mini-geek.com