`

URL encode

    博客分类:
  • j2ee
阅读更多

个人技术博客:http://demi-panda.com

 

发现现在几乎所有的网站都对url中的汉字和特殊的字符,进行了urlencode操作,也就是:

http://hi.baidu.com/%BE%B2%D0%C4%C0%CF%C8%CB/creat/blog/

这个样子,中间%形式的,肯定就是我的登录用户名称了吧。

为什么对这些字符进行了u的编码形式,是为了字符编码(gbk、utf8)还是为了不出现特殊的字符在url中?都知道要转,但是转了的真正好处呢。查看了网上的很多资料,也没有找到更加准确的说法。

url转义其实也只是为了符合url的规范而已。因为在标准的url规范中中文和很多的字符是不允许出现在url中的。

看一下php的urlencode的说明了。

urlencode — 编码 URL 字符串

string   urlencode   (  string   $str   )

返回字符串,此字符串中除了  -_.   之外的所有非字母数字字符都将被替换成百分号(% )后跟两位十六进制数,空格则编码为加号(+ )。此编码与 WWW 表单 POST 数据的编码方式是一样的,同时与  application/x-www-form-urlencoded   的媒体类型编码方式一样。由于历史原因,此编码在将空格编码为加号(+)方面与 RFC1738 编码(参见  rawurlencode() )不同。此函数便于将字符串编码并将其用于 URL 的请求部分,同时它还便于将变量传递给下一页。

标准的英文说明是:

"...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'(),"  [not including the quotes - ed] , and reserved characters used for their reserved purposes may be used unencoded within a URL."

那哪些字符是需要转化的呢?

1. ASCII 的控制字符

这些字符都是不可打印的,自然需要进行转化。

2. 一些非ASCII字符

这些字符自然是非法的字符范围。转化也是理所当然的了。

3. 一些保留字符

很明显最常见的就是“&”了,这个如果出现在url中了,那你认为是url中的一个字符呢,还是特殊的参数分割用的呢?

4. 就是一些不安全的字符了。

例如:空格。为了防止引起歧义,需要被转化为“+”。

明白了这些,也就知道了为什么需要转化了,而转化的规则也是很简单的。

按照每个字符对应的字符编码,不是符合我们范围的,统统的转化为%的形式也就是了。自然也是16进制的形式。

和字符编码无关

通过urlencode的转化规则和目的,我们也很容易的看出,urleocode是基于字符编码的。同样的一个汉字,不同的编码类型,肯定对应不同的urleocode的串。gbk编码的有gbk的encode结果。

apache等服务器,接受到字符串后,可以进行decode,但是还是无法解决编码的问题。编码问题,还是需要靠约定或者字符编码的判断解决。

因此,urleocode只是为了url中一些非ascii字符,可以正确无误的被传输,至于使用哪种编码,就不是eocode所关心和解决的问题了。

编码问题,不是urlencode所要解决的。

再结合 Java API 写一个例子,帮助进一步理解:

 

import java.net.*;


public class TestURI

{
  
public static void main(String[] args) throws Exception
 
 {
   
 String path = args[0];
  
  String query = args[1];

    
URI uri = new URI(
      "http",
      null,
      "smartstorage.yoyoyws.com",
      80,
      path,
      query,
      null);

    
    System.out.println("uri.toString(): " + uri.toString());
    System.out.println("uri.toASCIIString(): " + uri.toASCIIString());
 
 }

}



运行: 
java TestURI "/a/b/文件 1.txt" "versionId=ver_1"

结果:
uri.toString(): http://smartstorage.yoyoyws.com:80/a/b/文件%201.txt?versionId=ver_1
uri.toASCIIString(): http://smartstorage.yoyoyws.com:80/a/b/%E6%96%87%E4%BB%B6%201.txt?versionId=ver_1

 

servlet 实现了 doGet:
 public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
  {
    System.out.println("getRequestURI: " + request.getRequestURI());
    System.out.println("getParam: " + request.getParameter("param"));
  }

发送请求:
http://localhost:8080/你好?param=你好

tomcat 打印(tomcat 配置 URIEncoding="UTF-8"):
getRequestURI: /%E4%BD%A0%E5%A5%BD
getParam: 你好

结论:
tomcat 对 URL 中的 paramater 部分自动做 url decode,而不会对 URL 中的 path 部分做 url decode,需要应用开发人员来自己做 decode。

 

我们用 Java 作为 client 发送 HTTP 请求时,应该按照上面例子中的写法(调用 toASCIIString() )构造请求的 URL

参考资料:

另外 JDK 中也有一段详细的介绍:

http://download.oracle.com/javase/6/docs/api/java/net/URI.html#encode

http://www.blooberry.com/indexdot/html/topics/urlencoding.htm

http://cn.php.net/manual/zh/function.urlencode.php

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics