在項目開發中整合了WebSocket,原本沒什麼問題了,可是偶爾發現用IE瀏覽器打開web端不能推送消息,由於PC端與服務器創建鏈接失敗了。網上查了不少資料,前端
又看了看源碼,都不對症;又懷疑是SpringBoot版本的問題,可是換了版本仍是不行。樓主用demo跑了一遍發現沒有問題,但就是在項目中不能創建鏈接,再認真調試發java
現第一次創建鏈接的時候後臺有一個報錯,內容以下:web
2020-03-25 09:12:37.348 INFO 5580 --- [0.0-8080-exec-3] o.apache.coyote.http11.Http11Processor : Error parsing HTTP request header Note: further occurrences of HTTP request 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.Http11InputBuffer.parseRequestLine(Http11InputBuffer.java:476) ~[tomcat-embed-core-9.0.31.jar:9.0.31] at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:260) ~[tomcat-embed-core-9.0.31.jar:9.0.31] at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65) [tomcat-embed-core-9.0.31.jar:9.0.31] at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-9.0.31.jar:9.0.31] at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1639) [tomcat-embed-core-9.0.31.jar:9.0.31] at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.31.jar:9.0.31] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_202] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_202] at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.31.jar:9.0.31] at java.lang.Thread.run(Thread.java:748) [na:1.8.0_202]
報錯:Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC 3986說的很明白,貌似是什麼特殊字符引發的?真是奇了apache
怪了,樓主就是在創建WebSocket鏈接的時候傳了一個Json字符串而已,沒有什麼奇怪的字符纔對。用這個報錯描述再查百度了一下,終於找到了想要的答案。json
這個問題跟Tomcat版本有關,Tomcat高版本中的一個新特性:嚴格按照 RFC 3986規範進行訪問解析,而 RFC 3986規範定義了Url中只容許包含英文字母(a-zA-Z)、瀏覽器
數字(0-9)、-_.~4個特殊字符以及全部保留字符(RFC3986中指定了如下字符爲保留字符:! * ’ ( ) ; : @ & = + $ , / ? # [ ])。很明顯,確實是字符引發的報錯,樓主在url中傳tomcat
了一段json,傳入的參數中有」{「和「"」,花括號和雙引號不在RFC3986中的保留字段中,因此就報錯了。服務器
樓主的解決辦法是,創建鏈接的時候,在傳的json字符串參數中把「{「和」}」這兩個字符去掉,同時前端的json本身拼接,裏面的字段名和字符串都用單引號,好比創建鏈接app
正常的路徑是ws://127.0.0.1:8080/webSocket/{param},要接收一個參數做爲鑑權和業務須要,爲了不參數中的字符問題,拼接一個這樣的地址:url
ws://127.0.0.1:8080/webSocket/'userId':'3a05d7f26c8246bbbbec6b80da86c741','token':'090139d320b4257b43a4b3fb4faf9fda3527344e8145'
後臺接收到參數之後,本身加上先後的花括號,這樣就能夠解析json了,簡單粗暴,可是有效,哈哈哈。。。
固然了,網上正規的解決方法:
參考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
解決辦法就是:…/conf/catalina.properties中,找到最後註釋掉的一行
#tomcat.util.http.parser.HttpParser.requestTargetAllow=| ,
改爲
tomcat.util.http.parser.HttpParser.requestTargetAllow=|{}
而後去掉這句話的註釋。
這種方法樓主沒有試過,有興趣的同窗能夠本身嘗試一下。