URLEncode导致浏览器报CORS错误

发布于 2020-06-28  3929 次阅读


在做个一个文件上传服务时遇到的问题,文件上传到云服务商提供的文件的存储服务, 上传的大致逻辑为:

  • Step 1. client上报待上传的文件信息(文件名、类型...)
  • Step 2. 后端根据上报的文件信息生成签好名的上传URL返回给client
  • Step 3. client向上传URL进行PUT上传操作

在Step 2中后端使用Java的URLEncoder.encode方法对用户上传的文件名进行编码,然后对编码后的文件名进行签名运算,最后拼接成上传URL。

搜索(urlencoder.encode 空格变加号)发现URLEncoder.encode方法会将空格转换成+而不是常见的%20,这个问题导致后端拼接文件的下载链接是无效的,这边数据库里保存的是 xxx xx.jpg 而文件存储服务保存的是 xxx+xx.jpg

主流的解决方法也是很简单粗暴,将编码后的字符串中所有的+替换成空格:

URLEncoder.encode(name, "UTF-8").replaceAll("\\+", " ")

上面的代码将编码后的字符串中所有的加号直接替换成空格,这个就导致了本文最大的问题,浏览器在进行Step 3时报CORS错误,这个报错直接误导了排查的方向,检查了半天CORS设置等内容,经过多次尝试才发现只要文件名中包含空格就会报CORS错误,更据这个规律才重新回到正确的方向。

URLEncoder.encode之后已经是 符合W3C标准规定的编码后的字符串,正确的做法应该是将+替换成%20,使之符合RFC 2396规范,如下:

URLEncoder.encode(name, "UTF-8").replaceAll("\\+", "%20")

风雨兼程路,雨雪初霁时