在实现、测试OneFeed的tag功能时,发现tag c++
不能正常工作,
<a href="<%= '/posts?tag=' + t.name %>" class="..."><%= t.name %></a>
请求/posts?tag=c++
到达server端后,params[:tag]
的值为c
,导致数据库查询没有返回正确的结果。
原因是构造href
时没有对tag的name做encode,而+
恰好是URL规范里的特殊字符,它代表一个空格。
Within the query string, the plus sign is reserved as shorthand notation for a space. Therefore, real plus signs must be encoded.
所以,在把一个字符串拼接到URL里前,要先把它encode一下。
毕竟,不是每次测试时都有足够运气使用像c++
这样测试数据,提前发现bug。
在Rails里可以通过下面的方法来encode一个字符串,
URI.encode 'c++ java'
# => "c++%20java" 空格被encode,URL规范的特殊字符“+”没有被encode
ERB::Util.url_encode 'c++ java'
#=> "c%2B%2B%20java" 所有字符都被encode,包括像"+", "/", "?"这样的保留字符
<!-- fix: u是url_encode的alias -->
<a href="<%= '/posts?tag=' + u(t.name) %>" class="..."><%= t.name %></a>
关于URL decode,大部分web框架都会自动decode。
注意⚠️,“URL”也包括同一页面内的anchor
<a href="#need-to-encode-too">about</a>
<div id="need-to-encode-too">About us...</div>
另外,在准备测试数据时,别忘了中文;中文也是需要encode的。