IE上的 The valid characters are defined in RFC 7230 and RFC 3986 坑的解决方法

简介: IE上的 The valid characters are defined in RFC 7230 and RFC 3986 坑的解决方法

前言

日常开发中经常遇到一些莫名其妙的小问题,例如即将上线的项目在线上异常报错,但是在本地确可以正常运行。往往这猝不及防的小惊喜,真是让我们猿猿欲哭无泪啊。这里简单总结一下在IE浏览器上遇到的一个小坑,之前就因为这个小坑,着实慌了一把。


坑的由来

首先瞅瞅这坑长啥样子。如下图所示


上面的图片中,我们明确看到这样一行Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986,这句话的大致意思就是说请求头中包含了 RFC 7230 and RFC 3986规范中定义的非法字符。在这种情况下就会导致页面报400异常。  


触发上面报这种异常的代码片如下,只是一个简单的get请求

接下来我们来看看RFC 3986中到底是怎么规范的


RFC3986文档规定,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。RFC3986文档对Url的编解码问题做出了详细的建议,指出了哪些字符需要被编码才不会引起Url语义的转变,以及对为什么这些字符需要编码做出了相应的解释。


US-ASCII字符集中没有对应的可打印字符:Url中只允许使用可打印字符。US-ASCII码中的10-7F字节全都表示控制字符,这些字符都不能直接出现在Url中。同时,对于80-FF字节(ISO-8859-1),由于已经超出了US-ACII定义的字节范围,因此也不可以放在Url中。


保留字符:Url可以划分成若干个组件,协议、主机、路径等。有一些字符(:/?#[]@)是用作分隔不同组件的。例如:冒号用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数,等等。还有一些字符(!$&’()*+,;=)用于在每个组件中起到分隔作用的,如=用于表示查询参数中的键值对,&符号用于分隔查询多个键值对。当组件中的普通数据包含这些特殊字符时,需要对其进行编码。


RFC3986中指定了以下字符为保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ]

不安全字符:还有一些字符,当他们直接放在Url中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符,原因有很多。

空格:Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉。

引号以及<>:引号和尖括号通常用于在普通文本中起到分隔Url的作用

井号(#) 通常用于表示书签或者锚点

%:百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码

{}|\^[]`~:某一些网关或者传输代理会篡改这些字符


同时RFC 3986规范在tomcat7.0.73版本中就已经提出了,RFC 7230也是对前者的一些补充或者说是完善,所以在tomcat7.0.73及以上版本都会有这种问题。


如何填坑

解决上面问题,有如下几种思路。

  • 换用低版本的tomcat,既然你是tomcat7.0.73版本,及以上版本有这种问题,我们可以暂时的逃避这个问题,选择低版本的tomcat。


当然你也可以换低版本的tomcat,这里是不提倡的!前台编码两次(这样就不会引起linux上的IE浏览器错误)

。。。。。。好像有点扯远了,回归主题,接下来我们来看看encodeURI和encodeURIComponent

encodeURI(),用来encode整个URL,不会对下列字符进行编码:+ : / ; ?&。它只会对汉语等特殊字符进行编码

encodeURIComponent (),用来encodeURL中想要传输的字符串,它会对所有url敏感字符进行encode

在对url做encode操作时,一定要根据情况选择不同的方法。

例如url = “testGetRequest/testSimpleGet?name=+’爱琴孩’”

此时可以用encodeURI(url)

当你的参数中包含+ : / ; ?&请使用 encodeURIComponent 方法对这些参数单独进行编码。

例如url = “testGetRequest/testSimpleGet?parm=www.baidu.com/ccc/ddd?name=abcd”

所以我上面一开始遇到的问题只需要在前端编码一下就可以解决了


<Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" URIEncoding="utf-8"/>

encodeURIComponent()

他们都是用utf-8的编码方式,对于get请求,他的编码格式默认是按照浏览器的编码格式进行编码的,我们可以设置浏览器的编码格式,但是每个用户的浏览器的编码格式不可能都是一致的,这样我们的get请求的参数有时候就会出现乱码问题,但是如果我们自己在前端对get请求利用encodeURI()或者encodeURIComponent ()来统一设置成utf-8编码,这样我们在后台在用utf-8来解码,就不会出现乱码问题。

这里需要注意的一点,对于get请求的中文乱码问题,如果你没有在tomcat配置文件中设置编码格式,天真的想用request.setCharacterEncoding(“UTF-8”)来在后端设置后端的解码格式,这种方式对于get请求是无效的。同时有的小伙伴可能会想我们可以在项目的web.xml中设置编码过滤器。抱歉这种方式对于get请求也是无效的。

对于这种情况我们可以采用new String(request.getParameter(“name”).getBytes(“iso-8859-1”),”UTF-8”) 来进行二次编码解码过程,这种方式就能解决get请求中文乱码问题,当然我们也可以在tomcat的配置文件中设置统一编码格式。

encodeURI()

在前端对前端URL进行编码


下面介绍一下前端对URL进行编码的实现方法。 javascript可以使用的内置函数有


用post代替get请求,上面也说过了是get请求才会有这种情况,如果方便的话,我们完全可以采用post请求来实现这个功能


  • 总结:我的个人解决办法
  • 前端jsp页面:这里name传的参数是汉字(前端编码两次)
  • 后端解码一次(或者两次,我这里解码一次两次都可以);

  • 需要注意的一点,上面这种异常只是在IE上会出现,火狐,360,谷歌上是没有的。
  • 多注意点小细节。。。远离猝不及防的惊喜。如果对你遇到的问题有所帮助,记得推荐,谢谢!
目录
相关文章
|
缓存 JavaScript 前端开发
IE浏览器下ajax缓存导致数据不更新的解决方法
摘自:http://www.iefans.net/ie-ajax-json-shuju-huancun/ 最近做设计的时候遇到一个小问题,当你用jquery的getjson函数从后台获取数据的时候,IE浏览器会自动设置缓存,如果此时你对数据进行修改的时候刷新页面,IE并不会在页面显示你修改后的数据,因为你刷新的时候IE浏览器会查找缓存并显示你修改前的数据,最后在网上查了些资料终于解决了IE浏览器下的问题。
1312 0
|
Web App开发 .NET 开发框架
在ASP.NET中,IE与Firefox下载文件带汉字名时乱码的解决方法
解决办法: HttpContext.Current.Response.Clear(); HttpContext.Current.Response.Buffer = true; HttpContext.
1052 0
|
Web App开发 Windows
Windows7下32位IE异常不能打开解决方法
今天更新了Update及安装了一些软件,重启电脑后发现32位IE不能正常打开,而64位IE正常。 错误信息如下: 问题签名:  问题事件名称: BEX  应用程序名: iexplore.exe  应用程序版本: 8.
1064 0
IE不显示PNG解决方法一则
方法不是万能的,只针对如下情况: 刚刚安过QuickTime、或ITunes 开始-》运行-》regedit 启动注册表,找到 HKEY_CLASSES_ROOT\MIME\Database\Content Type 将其中中文名的以及乱码的都删除即可如[视频/mp4]
573 0