Base64 空格,加号问题(oss)
缘由:
在一个项目中,app请求tcpdump日志与记录的日志内容不一致
请求%2B
识别成 +
请求 +
识别成 空格
这个在base64解密的时候会出现异常,base64需要的是加号,而不是空格
造成的原因:
在js中,对url的加密分别由三种方式:
1 2 3 4 5 6 7 8 | escape( "aa+aa aa" ) "aa+aa%20aa" encodeURI( "aa+aa aa" ) "aa+aa%20aa" encodeURIComponent( "aa+aa aa" ) "aa%2Baa%20aa" |
第三种方式,+
变成%2B
java代码:
1 2 | System.out.println(URLEncoder.encode( "aa+aa aa" , "UTF-8" )); aa%2Baa+aa |
特么加号变成%2B,空格变成加号
如果是没经过加密,但是解密了
1 2 | System.out.println(URLDecoder.decode( "aa+aa aa" , "UTF-8" )); aa aa aa |
好吧,从这里就可以看出,为什么base64解密报错了
app端进行base64加密,内部含有+
,然后并没有进行url加密,直接传给后端,后端对其先进行Url解密,+
变成了空格,再进行base64解密,所以报错。
规范:
造成这种混乱局面的原因在于:
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。
本文作者:韩憨
本文链接:https://www.cnblogs.com/hanby/p/18100813
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步