Appearance
dotNet 的 Url Encode 说明
1. 在 dotnet 中
HttpUtility.UrlEncode默认使用 UTF-8 格式编码,该方法对冒号:和斜杠/也进行了编码,所以不能用于网址进行编码。同时需要注意的是该方法将空格编码成了加号+而不是%20;Server.UrlEncode该方法除了默认使用系统预设格式编码,其余的都与HttpUtility.UrlEncode一样;Uri.EscapeDataString适用于对网址参数编码,该方法对冒号:、斜杠/、空格[ ]和井号#都进行了编码,类似 JavaScript 中的encodeURIComponent方法;Uri.EscapeUriString适用于对网址进行编码(不包含参数),该方法并未对冒号:、斜杠/和井号#进行编码,类似 JavaScript 中的encodeURI方法;
2. 为什么空格有时候被编码成 %20 又有时候被编码成 +
URL 中的空格有时候被编码成 %20,有时候被编码成加号 +,曾经迷糊过一段时间,后来查了下资料才搞明白。
一个 URL 的基本组成部分包括协议(scheme)、域名、端口号、路径和查询字符串(路径参数和锚点标记就暂不考虑了)。路径和查询字符串之间用问号 ? 分隔。例如 http://www.example.com/index?param=1,路径为 index,查询字符串为 param=1。URL 中关于空格编码的不同正是与空格所在位置相关:空格被编码成加号 + 的情况只会在查询字符串部分出现,而被编码成 %20 则可以出现在路径和查询字符串中。
造成这种混乱局面的原因在于:W3C 标准规定,当 Content-Type 为 application/x-www-form-urlencoded 时,URL 中查询参数名和参数值中空格要用加号 + 替代,所以几乎所有使用该规范的浏览器在表单提交后,URL 查询参数中空格都会被编成加号 +。而在另一份规范(RFC 2396,定义 URI)里,URI 里的保留字符都需转义成 %HH 格式(Section 3.4 Query Component),因此空格会被编码成 %20,加号 + 本身也作为保留字而被编成 %2B,对于某些遵循 RFC 2396 标准的应用来说,它可能不接受查询字符串中出现加号 +,认为它是非法字符。所以一个安全的举措是 URL 中统一使用 %20 来编码空格字符。
Java 中的 URLEncoder 本意是用来把字符串编码成 application/x-www-form-urlencoded MIME 格式字符串,也就是说仅仅适用于 URL 中的查询字符串部分,但是 URLEncoder 经常被用来对 URL 的其他部分编码,它的 encode 方法会把空格编成加号 +,与之对应的是,URLDecoder 的 decode 方法会把加号 + 和 %20 都解码为空格,这种违反直觉的做法造成了当初我对空格 URL 编码问题的困扰。因此后来我的做法都是,在调用 URLEncoder.encode 对 URL 进行编码后(所有加号 + 已被编码成 %2B),再调用 replaceAll(“\\+”, “%20″),将所有加号 + 替换为 %20。