URL中通常会遇到特殊字符的处理。
问题描述
URL某一个参数中含有中文 或者”#$ ^ & * + =”等特殊符号。
如何处理才能正确传递参数?
正文
处理之前,先来点小知识。
URL中一些特殊字符及对应的Url编码如下:
Character | From UTF-8 |
---|---|
space | %20 |
! | %21 |
“ | %22 |
# | %23 |
$ | %24 |
% | %25 |
& | %26 |
‘ | %27 |
( | %28 |
) | %29 |
* | %2A |
+ | %2B |
, | %2C |
- | %2D |
. | %2E |
/ | %2F |
小案例:从一个中文字符的处理开始
restclient中,如果URL含有中文等非英文的特殊字符, 只需要使用URI::encode即可。比如下面这个例子:
网址是 http://example.com, 用户输入关键字“伊丽莎白好乖滴 ”查询:
url = 'http://example.com/search?keyword=伊丽莎白好乖滴'
RestClient.get(url)
这里,使用restclient发出get请求,会出现URI::InvalidURIError 的错误.
正确的打开方式可以像这样:
require 'addressable/uri'
url = 'http://example.com/search?keyword=伊丽莎白好乖滴'
RestClient.get(URI::encode(url))
这样,url中的中文字符会转化为下面这样的ascii码。
http://example.com/search?keyword=%E4%BC%8A%E4%B8%BD%E8%8E%8E%E7%99%BD%E5%A5%BD%E4%B9%96%E6%BB%B4
特别加餐:传递给参数的值中,含有&等特殊字符
需要特别提一句的是,如果你的URL是这样的:
url = 'http://example.com/search?keyword=XXX&city=shanghai&type=food'
而你希望将&s
传递给keyword, 使用URI::encode时,会是这样:
http://example.com/search?keyword=&s&city=shanghai&type=food
这里,因为URL中传递参数时,是用”&”符号隔开的,所以rest client识别的时候,会认为keyword这个参数并没有赋值, 而&s
中,s表示另一个参数, 且没有赋值,这样,发出请求后会报错,这种情况如何解决?做这样的处理:
URI::encode(url).sub("&", "%26")
encode后,将第一个&, 也就是&s
转变为”%26s”, 再传递给RestClient。
这里你可能想要问,为什么不直接传递”%26s”?
问得好!如果直接将”%26s”传递给keyword,经过URI::encode之后,keyword接收到的就会是:“%2526s”, why?Cause it will encode “%” to “%25”。
当然,不只是rest client,其他需要针对URL进行encoding的,也可以进行类似的处理。