技术记录

欲以犀利知性换啤酒,一杯又一杯。

  1. 1. 缘由:
  2. 2. 解决:
  3. 3. 解释:

缘由:

最近在通过中文名作为fileKey获取oss文件时,发现文件名中含有+号将无法获取到文件。
举个例子,假设资源路径为:

http://example-resource.oss-cn-beijing.aliyuncs.com/23232323/中文 + 文件-测试文件名.pdf

那么在浏览器中访问的文件名应该被转义为:

http://example-resource.oss-cn-beijing.aliyuncs.com/23232323/%E4%B8%AD%E6%96%87%20+%20%E6%96%87%E4%BB%B6-%E6%B5%8B%E8%AF%95%E6%96%87%E4%BB%B6%E5%90%8D.pdf

注意,在这里,空格被转义为 %20,而 + 没有进行任何处理。
同时,JavaScript 中的 encodeURI 和 new URL() 都是符合这一规则的。
但是在阿里云 OSS中,却无法解析+号,不清楚是被转义了还是怎么。。

解决:

无奈只能在存文件时,对加号编码成utf-8格式

URLEncoder.encode(“+”,”UTF-8”);

这里采用了java8中自带的URLEncoder进行编码.
测试oss存储和获取无问题了

然而,在前端对filename进行解码时,+号所编码的%2B并没有解码出来
Image text

解释:

造成这种混乱局面的原因在于:

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替换为+。

本文最后更新于 天前,文中所描述的信息可能已发生改变