今天部署环境,tomcat突然报这个错误,接口返回400。
网上查了下,大概原因是:
在tomcat 8.0.35之后 ,tomcat对url的参数做了比较规范的限制,必须按照RFC 7230 and RFC 3986规范,对于非保留字字符,如果不做转义处理,一律都会报The valid characters are defined in RFC 7230 and RFC 3986 错误。
解决这个问题的办法有几个:
- 把非保留字字符做转义
- 就是使用保留字字符
- 要么就是换比较底一点的tomcat版本
- 将json数据进行urlencode编码就可以了 即把json中的{}编码
补充知识点:
RFC3986文档规定,Url中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。
RFC3986中指定了以下字符为保留字符:
!*'();:@&=+$,/?#[]
不安全字符
还有一些字符,当他们直接放在Url中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符,原因有很多
->空格Url在传输的过程,或者用户在排版的过程,或者文本处理程序在处理Url的过程,都有可能引入无关紧要的空格,或者将那些有意义的空格给去掉
->引号以及<>引号和尖括号通常用于在普通文本中起到分隔Url的作用
->#通常用于表示书签或者锚点
->%百分号本身用作对不安全字符进行编码时使用的特殊字符,因此本身需要编码
->{}|\^[]`~某一些网关或者传输代理会篡改这些字符
完美的js URLEncode函数
当需要通过查询字符串传值给服务器时需要对get参数进行encode。
- escape()函数,不会encode
@*/+
(不推荐使用) - encodeURI()函数,不会encode
~!@#$&*()=:/,;?+'
(不推荐使用) - encodeURIComponent()函数,不会encode
~!*()
这个函数是最常用的
我们需要对encodeURIComponent函数,最一点修改:
function urlencode (str) {
str = (str + '').toString();
return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').
replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
}
本人觉得解决问题最简单粗暴的方式就是使用第三种方法,当然,最好还是要按照规范来写,长远考虑的话.