关于URL编码

来源:互联网 发布:从事期货行业知乎 编辑:程序博客网 时间:2024/06/02 00:29

          我们知道HTTP请求参数,必须使用请求参数名称与请求参数值,中间有等号(=)表示成对关系,现在问题来了,如果请求参数值本身包括"="符合怎么办?又或许你想发送的请求参数值是http://openhome.cc这个值呢?假设是GET请求,则不能直接这么在地址栏上输入:

http://openhome.cc/addBookmar.do?url=http://openhome.cc

1、保留字符

在URI的规范中定义了一些保留字符(Reserved character),如":"、“ /”、“?”、“&”、“=”、“@”、“%”等字符,在URI中都有它的作用。如果要在请求参数上表达URI中的保留字符,必须在%字符之后以十六进制表示方式,来表示该字符的八个位数值。

        例如,“:“字符真正储存时的八个位为00111010,用十六进制数值来表示则为3A,所以必须使用”%3A“来表示”:“;”/“字符储存时的八个为00101111,用十六进制表示为2F,所以必须使用“%2F”来表示“/”字符,所以若发送的请求参数值是http://openhome.cc,则必须使用以下格式:

http://openhome.cc/addBookmar.do?url=http%3A%2F%2Fopenhome.cc

这是URI规范中的百分比编码(Percent-Encoding),也就是俗称的URI编码或URL编码。如果想知道某个字符的URL编码是什么,在Java中可以使用java.net.URLEncoder类的静态encode()方法来做这个编码的动作(相对地,要译码则使用java.net.URLDecoder的静态decode()方法)。例如:

String text = URLEncoder.encode("http://openhome.cc","ISO-8859-1");

知道这些有什么用?例如,你想给某人一段URL,让他直接单击就可以连到你想要让他看到的网页,你给他的URL在请求参数部分就要注意URL编码。

不过在URI之前,HTTP在GET、POST时也对保留字作了规范,这与URI规范的保留字有所差别。其中一个差别就是在URI规范中,空格符的编码为%20,而在HTTP规范中空白的编码为”+“,java.net.URLEncoder类的静态方法encode()产生的字符串,空格符的编码就为”+“。

2、中文字符

另一个差别就是,URI规范的URL编码,针对的是字符UTF-8编码的八个位数值,如果请求参数都是ASCII字符,那没什么问题,因为UTF-8编码与在ASCII字符的编码部分是兼容的,也就是使用一个字节,编码方式就如先前所述。

但在非ASCII字符方面,如中文,在UTF-8编码下,会使用三个字节来表示。例如,”林“这个字在UTF-8编码下的三个字节,对应至十六进制数值表示就是E6、9E、97,所以在URI规范下,请求参数中要包括”林“这个中文,表示方式就是”%E6%9E%97“。例如:

http://openhome.cc/addBookmar.do?lastName=%E6%9E%97

有些初学者会直接打开浏览器输入如下所示内容,说:”URL也可以直接打开中文啊!“

http://openhome.cc/addBookmar.do?lastName=林

不过你可以将地址栏复制,黏贴到纯文本文件中,就会看到URI编码的结果,这其实是现在的浏览器很聪明,会自动讲上述的URI编码显示为中文。(上面一段我验证后在文本中其实也显示的是中文,暂还不知道什么原因。)无论如何,在URI规范上若以上方式发送请求参数,服务器端处理请求参数时,必须使用UTF-8编码来取得正确的林字符。我在这有个疑问,就是中文字不是3个字节吗?那解析的时候怎么就认定按3个字字节来解析,因为中文中3个字节单独的字节也是可以是特殊字符的。

然而在HTTP规范下的URL编码,并不限制使用UTF-8,例如在一个BIG5网页中,若窗体使用GET发送”林“这个中文字,则地址栏中会出现:

http://openhome.cc/addBookmar.do?lastName=%AA%4C

这是因为”林“这个中文字的BIG5编码为2个字节,若以十六进制表示,则分别为AA,4C。如果通过窗体发送,由于网页是BIG5编码,则浏览器会自动将”林“编码为”%AA%4C“,服务器端处理请求参数时,就必须指定BIG5编码,以取得正确的”林“汉字字符。

若使用java.net.URLEncoder类的静态encode()方法来作这个编码的动作,则可以像下面这样得到”%AA%4C“的结果:

string text = URLEncoder.encode(”林“,”BIG5“);

同理可推,如果网页是UTF-8编码,而你通过窗体发送,则浏览器会自动将”林“编码为”%E6%9E%97".若使用java.net.URLEncoder类的静态encode()方法来作这个编码的动作,则可以像下面这样得到”%E6%9E%97"的结果:

string text = URLEncoder.encode(”林“,”UTF-8“);

知道这些要作什么?你应该感觉到了:”我们会发送中文“。中文是如何编码的?到服务器后端又是如何译码的?这些问题必须要搞清楚。随便问个”为什么我收到的是乱码?“、”为什么数据库中是乱码?“,往往解决不了问题。如果具备这些基础知识,相信对你的理解有帮助。(摘自JSP&SERVLET学习笔记)

0 0
原创粉丝点击