url编码实践

此前碰到两个问题:

1. {}字符报错 rfc3986  

2. 含有% & 号的参数传递到tomcat,参数接收为null

3.webview没取到中文参数

 

第一个问题:

http://blog.csdn.net/flyingnet/article/details/78143429

 

 

今天在Tomcat 7.0.81进行测试时,发现一个BUG,前台通过ajax访问后台controller时,无法进行页面跳转。Tomcat控制台报错,错误信息如下:

信息: Error parsing HTTP request header
 Note: further occurrences of HTTP header parsing errors will be logged at DEBUG level.
java.lang.IllegalArgumentException: Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986
at org.apache.coyote.http11.InternalAprInputBuffer.parseRequestLine(InternalAprInputBuffer.java:235)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1028)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2549)
at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2538)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:662)

经过分析,发现问题是由URL中一个参数params引起的,

这个参数通过JSON2.stringify()转换为一个对象数组,所以包含了{},而恰恰就是这一步在Tomcat 7.0.81版本中出现 了问题,请求链接都是400的状态,就是请求参数有误。

这个问题是由于Tomcat的新版本中增加了一个新特性,就是严格按照 RFC 3986规范进行访问解析,而 RFC 3986规范定义了Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符(RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。(连带%,本身转义符,所以不属于保留字符,)

既然分析出了原因,那么就要找解决方案了,其实,解决办法很简单,就是使用encodeURIComponent或encodeURI对包含{}的URL进行编码,这样就可以解决该问题。当然,还有一种办法就是更换Tomcat为支持大括号{}的版本。

 

 

 

{}进去之后,tomcat不接收报错,解决方法,urlencode通过

注意urlencode 某些实现是不能对保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ]  进行编码的(废话,关键字被你编码了,服务器还怎么取参数),但可以对%进行编码,编码出%25

 

 

 

第二个问题:

http://lwjlaser.iteye.com/blog/1055359

 

测试最近的代码发现,有一个servlet处理通过post方式传递过来的参数的时候偶尔出现乱码,并提示错误“org.apache.tomcat.util.http.Parameters processParameters  Parameters: Character decoding failed”,开始以为是编码问题,google了一大堆关于编码的问题,各种测试还是无法解决这个问题。于是把出错的参数调了出来用类似二分法的方式慢慢筛查参数,最后锁定在参数中的%上,因为要传递的参数不是经常出现%,所以就出现偶尔出错的现象。解决方法就是把参数中的“%”替换为“%25”,修改代码为

Java代码  收藏代码
  1. parameter = parameter.replace("%","%25")  

,问题解决。 
下面附录是URL中的特殊字符: 

Java代码  收藏代码
  1. URL中一些字符的特殊含义,基本编码规则如下:   
  2. 1、空格换成加号(+)   
  3. 2、正斜杠(/)分隔目录和子目录   
  4. 3、问号(?)分隔URL和查询   
  5. 4、百分号(%)制定特殊字符   
  6. 5、#号指定书签   
  7. 6、&号分隔参数   
  8.   
  9. 如果需要在URL中用到,需要将这些特殊字符换成相应的十六进制的值   
  10. +   %20   
  11. /   %2F   
  12. ?   %3F   
  13. %   %25   
  14. #   %23   
  15. &   %26  
 
那为什么有些form可以提交特殊字符,那是浏览器给处理了
https://www.cnblogs.com/hypo106/p/4988982.html
针对+ 号的处理,针对不同的业务场景需要不同的处理方案,描述下几种场景:
1. 非Ajax 请求
    可以直接使用Form 表单的 GET ,POST 的urlencode 协议,自动实现+ => %2B 的转化
2.  Ajax 请求
    * GET 请求 : 很无奈,只能使用方案3 ,人为进行+ 号转化。
    * POST 请求( 同一应用,非跨域请 求) :  使用encodeURIComponent +  _input_charset=utf-8 指定编码进行处理。
 
 
 
第三个问题:
移动端的webview并未将中文转义,而一般浏览器都会作这道工序,所以疏忽了这点
http://www.360doc.com/content/14/0311/11/14423330_359516565.shtml

 

posted on 2017-11-27 15:50  silyvin  阅读(297)  评论(0编辑  收藏  举报