The valid characters are defined in RFC 7230 and RFC 3986

来源:互联网 发布:js 动态修改url参数 编辑:程序博客网 时间:2024/06/15 23:37

出现异常:

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.InternalInputBuffer.parseRequestLine(InternalInputBuffer.java:189)    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.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316)    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)    at java.lang.Thread.run(Thread.java:745)

先附上解决方法:

最终解决方法:假如 data字符串 出现特殊字符  如:   04140725|04140735|    就会报错!此时,我们将window.location = url + "?" + paramName + "=" + data;改为:window.location = url + "?" + paramName + "=" + encodeURIComponent(data);

以下是网上收集到的关于此类异常的讲解:

解决方法: 上面异常发生在前台页面向后台发送get请求的时候,错误内容说得很清楚,request中有非法字符,在RFC7230和RFC3986规范中都定义为非法字符。发生异常的web容器为tomcat7.0.75,而本地使用tomcat7.0.65时没发生报错,说明是因为更高版本的tomcat对request参数安全校验更加严格了。网上很多人把tomcat降级,其实这样不对的,我们应该找到问题产生的根本原因,上面不是说非法字符引起的吗,我们就一个个过滤,看到底是因为哪个非法字符造成的。我们只需对怀疑的字符一个个进行尝试就可以找到答案。最终,笔者找到自己发生异常的原因是因为"|"竖线这个字符引起的,当时笔者想当然认为这个字符没问题,传参时没有进行编码,没想到高版本对它进行了限制。更多的信息可以查看RFC7230和RFC3986规范。
做java的web开发有段日子了,有个问题老是困扰着我,就是乱码问题,基本上是网上查找解决方案(网上资料真的很多),都是一大堆的介绍如何解决此类的乱码问题,但是没几个把问题的来龙去脉说清楚的,有时候看了些文章后,以为自己懂了,但是在开发中乱码问题又像鬼魂一样出来吓人,真是头大了!这篇文章是我长时间和乱码做斗争的一些理解的积累,还希望有更多的朋友给出指点和补充。 form有2中方法把数据提交给服务器,getpost,分别说下吧。 (一)get提交 1.首先说下客户端(浏览器)的form表单用get方法是如何将数据编码后提交给服务器端的吧。     对于get方法来说,都是把数据串联在请求的url后面作为参数,如:http://localhost:8080/servlet?msg=abc (很常见的一个乱码问题就要出现了,如果url中出现中文或其它特殊字符的话,如:http://localhost:8080 /servlet?msg=杭州,服务器端容易得到乱码),url拼接完成后,浏览器会对url进行URL encode,然后发送给服务器,URL encode的过程就是把部分url做为字符,按照某种编码方式(如:utf-8,gbk等)编码成二进制的字节码,然后每个字节用一个包含3个字符的字符串 "%xy" 表示,其中xy为该字节的两位十六进制表示形式。我这里说的可能不清楚,具体介绍可以看下java.net.URLEncoder类的介绍在这里。了解了URL encode的过程,我们能看到2个很重要的问题,第一:需要URL encode的字符一般都是非ASCII的字符(笼统的讲),再通俗的讲就是除了英文字母以外的文字(如:中文,日文等)都要进行URL encode,所以对于我们来说,都是英文字母的url不会出现服务器得到乱码问题,出现乱码都是url里面带了中文或特殊字符造成的;第二:URL encode到底按照那种编码方式对字符编码?这里就是浏览器的事情了,而且不同的浏览器有不同的做法,中文版的浏览器一般会默认的使用GBK,通过设置浏览器也可以使用UTF-8,可能不同的用户就有不同的浏览器设置,也就造成不同的编码方式,所以很多网站的做法都是先把url里面的中文或特殊字符用 javascript做URL encode,然后再拼接url提交数据,也就是替浏览器做了URL encode,好处就是网站可以统一get方法提交数据的编码方式。 完成了URL encode,那么现在的url就成了ASCII范围内的字符了,然后以iso-8859-1的编码方式转换成二进制随着请求头一起发送出去。这里想多说几句的是,对于get方法来说,没有请求实体,含有数据的url都在请求头里面,之所以用URL encode,我个人觉的原因是:对于请求头来说最终都是要用iso-8859-1编码方式编码成二进制的101010.....的纯数据在互联网上传送,如果直接将含有中文等特殊字符做iso-8859-1编码会丢失信息,所以先做URL encode是有必要的。    2。服务器端(tomcat)是如何将数据获取到进行解码的。    第一步是先把数据用iso-8859-1进行解码,对于get方法来说,tomcat获取数据的是ASCII范围内的请求头字符,其中的请求url里面带有参数数据,如果参数中有中文等特殊字符,那么目前还是URL encode后的%XY状态,先停下,我们先说下开发人员一般获取数据的过程。通常大家都是request.getParameter("name")获取参数数据,我们在request对象或得的数据都是经过解码过的,而解码过程中程序里是无法指定,这里要说下,有很多新手说用request.setCharacterEncoding("字符集")可以指定解码方式,其实是不可以的,看servlet的官方API说明有对此方法的解释:Overrides the name of the character encoding used in the body of this request. This method must be called prior to reading request parameters or reading input using getReader().可以看出对于get方法他是无能为力的。那么到底用什么编码方式解码数据的呢,这是tomcat的事情了,默认缺省用的是 iso-8859-1,这样我们就能找到为什么get请求带中文参数为什么在服务器端得到乱码了,原因是在客户端一般都是用UTF-8或GBK对数据 URL encode,这里用iso-8859-1方式URL decoder显然不行,在程序里我们可以直接 Java代码    1. new String(request.getParameter("name").getBytes("iso-8859-1"),"客户端指定的URL encode编码方式") 还原回字节码,然后用正确的方式解码数据,网上的文章通常是在tomcat里面做个配置 Xml代码    1. <Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK"/> 这样是让tomcat在获取数据后用指定的方式URL decoder,URL decoder的介绍在这里 (一)post提交 1.客户端(浏览器)的form表单用post方法是如何将数据编码后提交给服务器端的。 在post方法里所要传送的数据也要URL encode,那么他是用什么编码方式的呢?    在form所在的html文件里如果有段<meta http-equiv="Content-Type" content="text/html; charset=字符集(GBK,utf-8等)"/>,那么post就会用此处指定的编码方式编码。一般大家都认为这段代码是为了让浏览器知道用什么字符集来对网页解释,所以网站都会把它放在html代码的最前端,尽量不出现乱码,其实它还有个作用就是指定form表单的post方法提交数据的 URL encode编码方式。从这里可以看出对于get方法来数,浏览器对数据的URL encode的编码方式是有浏览器设置来决定,(可以用js做统一指定),而post方法,开发人员可以指定。 2。服务器端(tomcat)是如何将数据获取到进行解码的。 如果用tomcat默认缺省设置,也没做过滤器等编码设置,那么他也是用iso-8859-1解码的,但是request.setCharacterEncoding("字符集")可以派上用场。 我发现上面说的tomcat所做的事情前提都是在请求头里没有指定编码方式,如果请求头里指定了编码方式将按照这种方式编码。

javascript对url进行encode的两种方式

javascript可以使用的内置函数有encodeURI()encodeURIComponent()他们都是用utf-8的编码方式encodeURI(),用来encode整个URL,不会对下列字符进行编码:+ : / ; ?&。它只会对汉语等特殊字符进行编码encodeURIComponent (),用来enode URL中想要传输的字符串,它会对所有url敏感字符进行encode在对url做encode操作时,一定要根据情况选择不同的方法。例如url = 'www.xxx.com/aaa/bbb.do?parm1=罗'此时可以用encodeURI(url)当你的参数中包含+ : / ; ?&请使用 encodeURIComponent 方法对这些参数单独进行编码。例如url = 'www.xxx.com/aaa/bbb.do?parm1=www.xxx.com/ccc/ddd?param=abcd'encodeURI(url)绝对无法满足要求,因为param1=www.xxx.com/ccc/ddd?param=abcd,这个参数是不能按照我们的要求encode的,此时应该这样单独对参数进行encodeurl = 'www.xxx.com/aaa/bbb.do?parm1=' + encodeURIComponen('www.xxx.com/ccc/ddd?param=abcd')编码后的url的值为www.xxx.com/aaa/bbb.do?parm1=www.xxx.com%2Fccc%2Fddd%3Fparam%3Dabcd此时接受此请求的服务端就能够成功取得param1=www.xxx.com/ccc/ddd?param=abcd
2 0
原创粉丝点击