美文网首页
URL编码问题

URL编码问题

作者: 猫尾草 | 来源:发表于2019-05-13 19:37 被阅读0次

1. 几点说明:

  • 使用浏览器发送请求,在地址栏输入url,浏览器都会帮你进行编码;
  • 发送http请求的框架,例如HttpClient以及本文要说的zuul,并不会自动编码,需要你对参数进行编码,例如:URLEncoder.encoder("你的请求参数");
  • springboot框架,controller中获取参数时,会自动进行解码;

2. 问题

媒体项目用到ceph做存储工具,使用AmazonS3来访问ceph对象存储,AmazonS3不支持文件夹/文件的名称以空格开头,所以前端已经将空格字符禁用。但是某天在server端还是出现了空格导致了S3访问失败的问题,controller中打印请求得到:

System.out.println(request.getQueryString());
System.out.println(request.getParameter("pathPrefix"));
pageIndex=0&pageSize=10&userName=develop&bucketName=0002&pathPrefix=+hahaha
 hahaha

可以明显看到,pathPrefix在请求中是+hahaha,而实际得到的是hahaha+变成了空格。

3. 分析

URL编码有两套编码方式。

  • 编码方式1:html4
    空格编码为++编码为%2B
  • 编码方式2:RFC-3986
    空格编码为%20+编码为%2B

有两个注意点:

  • 在一次编解码中,这两个编码方式不能混用,因为空格的编码不一致(其他的没研究)
  • RFC-3986不编码直接解码没有问题,html4不编码直接解码不行,会把+变空格

3. 解决问题

我们看看我们常用的URL编解码在java代码中的表现,测试代码:

String str = "aaa+aaa aaa";
System.out.println("ENCODE="+URLEncoder.encode(str, "utf-8"));
System.out.println("DECODE="+URLDecoder.decode(str,"utf-8"));
ENCODE=aaa%2Baaa+aaa
DECODE=aaa aaa aaa

可以看到,编码时,+编码为%2B,空格编码为+;解码时,+变成了空格,空格不变。明显这是采用的html4方式。
到这里基本明白了上面错误的原因,项目中zuul分发时没做url编码,而微服务的springboot默认启用了url解码,将正常的+变成了空格,从而导致错误。
zuul的配置加上force-original-query-string-encoding: true,问题解决。

4.tips

  • java代码中,如果想指定用RFC-3986编码,使用org.springframework.web.util.UriUtils类,或者
URLEncoder.encode("你 好", "utf-8").replaceAll("\\+", "%20");
  • 每个浏览器的编码方式不一样,最好自己使用javascript编码,浏览器就不会再编码,使编码统一。

参考:

相关文章

网友评论

      本文标题:URL编码问题

      本文链接:https://www.haomeiwen.com/subject/esgeaqtx.html