RestClient:URL中特殊字符的处理

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的,也可以进行类似的处理。

参考

URL with square brackets: URI::InvalidURIError

HTML URL Encoding Reference