Loading... <div class="tip share">请注意,本文编写于 1724 天前,最后修改于 1694 天前,其中某些信息可能已经过时。</div> ## 问题 在对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 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 1 如果觉得我的文章对你有用,请随意赞赏