Loading...
## 问题
在对URL进行encode编码的时候,URL中的空格有时候被编码成`%20`,有时候被编码成加号`+`。大多数情况下,这两种编码都可以工作,但个别情况下,编码为`+`的URL存在问题,并不能正常访问。
## 原因
一个URL的基本组成部分包括协议(scheme),域名,端口号,路径和查询字符串(路径参数和锚点标记就暂不考虑了)。路径和查询字符串之间用问号?分离。
例如`http://www.example.com/index?param=1`,路径为`index`,查询字符串(Query String)为`param=1`。
以上例子中URL中关于空格的编码正是与空格所在位置相关:空格被编码成加号+的情况只会在查询字符串部分出现,而被编码成%20则可以出现在路径和查询字符串中。
造成这种混乱局面的原因在于:[W3C标准规定](http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.1),当`Content-Type`为`application/x-www-form-urlencoded`时,URL中查询参数名和参数值中空格要用加号+替代,所以几乎所有使用该规范的浏览器在表单提交后,URL查询参数中空格都会被编成加号`+`。
而在另一份规范([RFC 2396](http://www.ietf.org/rfc/rfc2396.txt),定义URI)里, URI里的保留字符都需转义成`%HH`格式(Section 3.4 Query Component),因此空格会被编码成`%20`,加号`+`本身也作为保留字而被编成`%2B`,对于某些遵循`RFC 2396`标准的应用来说,它可能不接受查询字符串中出现加号`+`,认为它是非法字符。所以一个安全的举措是URL中统一使用`%20`来编码空格字符。
## 解决方法(java)
Java中的URLEncoder本意是用来把字符串编码成`application/x-www-form-urlencoded MIME`格式字符串,也就是说仅仅适用于URL中的查询字符串部分,但是`URLEncoder`经常被用来对URL的其他部分编码,它的`encode`方法会把空格编成加号`+`,与之对应的是,`URLDecoder`的`decode`方法会把加号`+`和`%20`都解码为空格,这种做法造成了URL编码问题的混乱。
比较可靠的做法是,在调用`URLEncoder.encode`对URL进行编码后(所有加号`+`已被编码成`%2B`),再调用`replaceAll(“\\+”, “%20″)`,将所有加号`+`替换为`%20`。例子如下:
```java
public static String urlEncodeURL(String url) {
try {
String result = URLEncoder.encode(url, "UTF-8");
result = result.replaceAll("%3A", ":").replaceAll("%2F", "/").replaceAll("\\+", "%20");//+实际上是 空格 url encode而来
return result;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
```
最后修改:2020 年 04 月 02 日 10 : 58 AM
© 允许规范转载
赞赏
如果觉得我的文章对你有用,请随意赞赏
×Close
赞赏作者
扫一扫支付


支付宝支付
微信支付
本文探讨了URL编码时空格被编码为`%20`和`+`的现象,解释了其原因在于不同规范的冲突。W3C标准规定查询字符串中的空格应编码为`+`,而RFC 2396建议编码为`%20`。Java的`URLEncoder.encode`方法可能导致混淆,建议在编码后替换所有`+`为`%20`以确保兼容性。提供了一个示例方法`urlEncodeURL`用于正确处理URL编码。

被折叠的 条评论
为什么被折叠?



