(本文档仅供参考)
本地测试在tomcat 9中测试如下URL链接, 测试串(基于产品自带的例子):http://localhost:8080/smartbi/vision/openresource.jsp?paramsInfo=[{"name":"产品名称参数","value":"汽水","displayValue":"汽水"}]&resid=I4028812115561f6c0144956d0aa20117&showtoolbar=true&refresh=true&user=admin&password=admin
发现访问的时候提示“HTTP Status 400 -错误的请求”,不传参打开是正常访问的,这个是为什么?
经验证发现是由于tomcat中间件的问题导致,这应该是一个比较普通存在的问题。
7.0.69+
8.0.39+
8.5.7+
请求的URL在编码后的中文字符串带反斜杠,这是RFC文档中规定的不安全字符,Tomcat在高版本中增加的安全验证,凡是RFC 3986中非URL可携带的字符,都会返回400错误。
这个问题根本都还没有进入到业务层就已经被拦截返回了。
通常用于表示书签或者锚点
最优解决方案:对于所有服务器传参带特殊符号或者中文的时候必须使用encodeURLComponent 进行编码(在java中对应为 java.net.URLEncoder.encode("...","UTF-8"),但实际中因为不同应用服务器编码不同,有可能使用encodeURLComponent 编码后服务器认为还是存在非法字符,这时候URL传参依然是不生效的,因此是不建议在URL中使用中文,对于带中文的传参建议使用post方式(具体可参考: post方式传参.html)或者Base64编码后传递paramsInfoBase64,具体可参考:从第三方系统中打开Smartbi资源 此文档中的 3、附件参数 部分:
补充方案:以下方案在部分版本Tomcat可以解决URL带中文和特殊字符传参的问题,如果添加后没有解决,就是这个Tomcat版本不支持这样的方式,请使用【最优解决方案所提供的建议】:
1)配置tomcat/conf下的catalina.properties(tomcat 9测试发现编码后依然存在问题),添加或者修改:
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
此修改添加或者修改后一般可以解决传参带特殊符号的问题。
2)在cong/server.xml设置编码,对于未修改过端口号的server.xml,找到
<Connector port="8080" 和<Connector port="8009",在节点中增加属性URIEncoding="UTF-8",修改后两个节点内容分别是
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8"/>和
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" URIEncoding="UTF-8"/>,这个方法可以解决传参带中文乱码的问题,但传参带特殊字符的话没有办法处理。
3)如果上述两步都改了还是会报400等错误,则继续修改server.xml,找到<Connector port="8080" ,增加2个属性:relaxedPathChars="|{}[]," relaxedQueryChars="|{}[],",加上第二步的修改,该节点内容最终是
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" relaxedPathChars="|{}[]," relaxedQueryChars="|{}[],"/>