The valid characters are defined in RFC 7230 and RFC 3986

一. 錯誤描述

 

公司由於受外部軟件的限制, 暫時只能使用 IE8,  IE8大家都知道, 對標準的 W3C的支持不是很好,  兼容性容易出現問題

系統是在 Tomcat7中發佈, Tomcat8中開發的

錯誤代碼

十月 21, 2019 5:02:47 下午 org.apache.coyote.http11.AbstractHttp11Processor process
信息: 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.AbstractNioInputBuffer.parseRequestLine(AbstractNioInputBuffer.java:285)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1045)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1539)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1495)
	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)

 

二. 原因分析

這個問題是高版本tomcat中的新特性:就是嚴格按照 RFC 3986規範進行訪問解析,而 RFC 3986規範定義了Url中只允許包含英文字母(a-zA-Z)、數字(0-9)、-_.~4個特殊字符以及所有保留字符(RFC3986中指定了以下字符爲保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。而我們的系統在通過地址傳參時,在url中傳了一段json,傳入的參數中有"{"不在RFC3986中的保留字段中,所以會報這個錯。

根據(https://bz.apache.org/bugzilla/show_bug.cgi?id=60594) ,從以下版本開始,有配置項能夠關閉/配置這個行爲:
8.5.x系列的:8.5.12 onwards
8.0.x系列的:8.0.42 onwards
7.0.x系列的:7.0.76 onwards

 

三.處理方法

(1)使用Tomcat7.0.69之前的版本

(2)對url的特殊字符進行轉義

           1、escape 和 unescape

           2、encodeURI 和 decodeURI

           3、encodeURIComponent 和 decodeURIComponent

(3)修改tomcat配置文件

          在conf/catalina.properties 中添加   tomcat.util.http.parser.HttpParser.requestTargetAllow=|{} 

           注意中文的問題

 

四.js對url進行編碼和解碼(三種方式區別)

URL: 只有 0-9[a-Z] $ - _ . + ! * ' ( ) , 以及某些保留字,才能不經過編碼直接用於 URL。

            例如:搜索的中文關鍵字,複製網址之後再粘貼就會發現該URL已經被轉碼。

1、escape 和 unescape

原理:對除ASCII字母、數字、標點符號 @  *  _  +  -  .  / 以外的其他字符進行編碼

    編碼:escape('http://www.baidu.com?name=zhang@xiao@jie&order=1')

    結果:"http%3A//www.baidu.com%3Fname%3Dzhang@xiao@jie%26order%3D1"

    編碼:escape('張')

    結果:"%u5F20"

    解碼:unescape("http%3A//www.baidu.com%3Fname%3Dzhang@xiao@jie%26order%3D1")

    結果:"http://www.baidu.com?name=zhang@xiao@jie&order=1"

    編碼:unescape("%u5F20")

    結果:"張"

2、encodeURI 和 decodeURI

原理:返回編碼爲有效的統一資源標識符 (URI) 的字符串,不會被編碼的字符:! @ # $ & * ( ) = : / ; ? + '

   encodeURI()是Javascript中真正用來對URL編碼的函數

    編碼:encodeURI('http://www.baidu.com?name=zhang@xiao@jie&order=1')

    結果:"http://www.baidu.com?name=zhang@xiao@jie&order=1"

    解碼:decodeURI("http%3A//www.baidu.com%3Fname%3Dzhang@xiao@jie%26order%3D1")

    結果:"http%3A//www.baidu.com%3Fname%3Dzhang@xiao@jie%26order%3D1"

3、encodeURIComponent 和 decodeURIComponent

原理:對URL的組成部分進行個別編碼,而不用於對整個URL進行編碼

    編碼:encodeURIComponent('http://www.baidu.com?name=zhang@xiao@jie&order=1')
    結果:"http%3A%2F%2Fwww.baidu.com%3Fname%3Dzhang%40xiao%40jie%26order%3D1"

    解碼:decodeURIComponent("http%3A%2F%2Fwww.baidu.com%3Fname%3Dzhang%40xiao%40jie%26order%3D1")

    結果:"http://www.baidu.com?name=zhang@xiao@jie&order=1"

 

encodeURI() 函數和encodeURIComponent()函數的區別:前者只對中文部分轉碼和部分不能解析特殊字符編碼,後者還會對encodeURI() 不能轉移的字符串轉義。範圍 encodeURI()  小於 encodeURIComponent(), 對url解析建議採用 encodeURI() 。

// 參考:  https://www.cnblogs.com/z-one/p/6542955.html

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章