缘由:
最近在通过中文名作为fileKey获取oss文件时,发现文件名中含有+号将无法获取到文件。
举个例子,假设资源路径为:
http://example-resource.oss-cn-beijing.aliyuncs.com/23232323/中文 + 文件-测试文件名.pdf
那么在浏览器中访问的文件名应该被转义为:
注意,在这里,空格被转义为 %20,而 + 没有进行任何处理。
同时,JavaScript 中的 encodeURI 和 new URL() 都是符合这一规则的。
但是在阿里云 OSS中,却无法解析+号,不清楚是被转义了还是怎么。。
解决:
无奈只能在存文件时,对加号编码成utf-8格式
URLEncoder.encode(“+”,”UTF-8”);
这里采用了java8中自带的URLEncoder进行编码.
测试oss存储和获取无问题了
然而,在前端对filename进行解码时,+号所编码的%2B并没有解码出来
解释:
造成这种混乱局面的原因在于:
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(“%2B”, “+″),将文件中所有%2B替换为+。