1.背景介紹
最近做新聞資訊類相關項目,涉及到富文本,在富文本上傳本地圖片並添加資訊后將內容通過接口入庫時接口長時間無響應。
經查,前端在富文本上傳本地圖片時設置了圖片數據用Base64編碼字符串進行傳輸,而Base64文本會隨着文件的增大而變得特別長,例如我本地上傳了一個400Kb的圖片,轉換后的Base64文本多達544408個字符,傳入接口后,接口也無響應超時,同時整個網頁都崩潰了。
查詢日志,顯示如下報錯信息:
java.lang.IllegalArgumentException: Request header is too large at org.apache.coyote.http11.AbstractNioInputBuffer.parseHeaders(AbstractNioInputBuffer.java:392) at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1025) at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:674) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) 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)
2.錯誤分析
原因:請求頭Header超過了tomcat的限值,需要修改tomcat的配置項
3.解決方案
因為我的項目是SpringBoot項目,所以此時分兩種情況:
3.1 本地服務,因為使用的是springboot的內置tomcat服務器,所以在application.properties文件中添加
server.tomcat.max-http-post-size=-1
server.tomcat.max-http-header-size=102400
3.2 當項目部署在服務器上時,此時使用的非內置tomcat,需在tomcat安裝目錄/config/server.xml文件的Connector配置中增加2個參數:maxPostSize="-1" maxHttpHeaderSize ="102400"
具體如下:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
maxHttpHeaderSize ="102400" maxPostSize="-1"/>
PS:
maxHttpHeaderSize表示請求頭大小,缺省為8192(8KB),此處應內容較大,改為102400,可視具體情況修改。
maxPostSize表示post請求大小,缺省為2097152(2MB),此屬性設置為小於零的值來禁用該限制。所以此處設置為-1。
另外,需要注意的是,不同版本的tomcat設置maxPostSize是不同的,在7.0.63版本之前,當小於或等於0可以取消大小限制,在7.0.63(包含)之后,需設置成小於0才能取消大小限制。
(這里之前查了很多回答都說將maxPostSize設置為0,但試驗之后發現不起作用,后面查tomcat官方文檔,才發現這處區別,記錄一下。)
PPS 在tomcat限制上傳文件的大小配置
1.如果是springboot內置tomcat,配置如下:
spring.servlet.multipart.enabled =true spring.servlet.multipart.file-size-threshold =0 spring.servlet.multipart.max-file-size = 100Mb spring.servlet.multipart.max-request-size=100Mb
2.linux tomcat服務器則到webapps\manager\WEB-INF\web.xml下找到
<multipart-config>
<!-- 50MB max -->
<max-file-size>52428800</max-file-size>
<max-request-size>52428800</max-request-size>
<file-size-threshold>0</file-size-threshold>
</multipart-config>
根據實際情況進行相應的修改。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
以下為相關內容拓展:
1> GET URL長度限制
在Http1.1協議中並沒有提出針對URL的長度進行限制,RFC協議里面是這樣描述的,HTTP協議並不對URI的長度做任何的限制,服務器端 必須能夠處理任何它們所提供服務多能接受的URI,並且能夠處理無限長度的URI,如果服務器不能處理過長的URI,那么應該返回414狀態碼。
雖然Http協議規定了,但是Web服務器和瀏覽器對URI都有自己的長度限制。
服務器的限制:我接觸的最多的服務器類型就是Nginx和Tomcat,對於url的長度限制,它們都是通過控制http請求頭的長度來進行限制 的,nginx的配置參數為large_client_header_buffers,tomcat的請求配置參數為 maxHttpHeaderSize,都是可以自己去進行設置。
client_header_buffer_size 512k;
large_client_header_buffers 7 512k;
瀏覽器的限制:每種瀏覽器也會對url的長度有所限制,下面是幾種常見瀏覽器的url長度限制:(單位:字符)
-
IE : 2803
-
Firefox:65536
-
Chrome:8182
-
Safari:80000
-
Opera:190000
對於get請求,在url的長度限制范圍之內,請求的參數個數沒有限制。
2. Post數據的長度限制
Post數據的長度限制與url長度限制類似,也是在Http協議中沒有規定長度限制,長度限制可以在服務器端配置最大http請求頭長度的方式來實現。 nginix默認限制1M
可以選擇在http{ }中設置:
client_max_body_size 20m;
也可以選擇在server{ }中設置:
client_max_body_size 20m;
還可以選擇在location{ }中設置:
client_max_body_size 20m;
三者到區別是:http{}中控制着所有nginx收到的請求。而報文大小限制設置在server{}中,則控制該server收到的請求報文大小,
同理,如果配置在location中,則報文大小限制,只對匹配了location 路由規則的請求生效。
http{
#控制全局nginx所有請求報文大小
#client_max_body_size 20m;
server{
#控制該server的所有請求報文大小
#client_max_body_size 20m;
location a {
}
location b{
#控制滿足該路由規則的請求報文大小
#client_max_body_size 20m;
}
}
server {
}
}
3. Cookie的長度限制
Cookie的長度限制分這么幾個方面來總結。
(1) 瀏覽器所允許的每個域下的最大cookie數目,沒有去自己測試,從網上找到的資料大概是這么個情況
-
IE :原先為20個,后來升級為50個
-
Firefox: 50個
-
Opera:30個
-
Chrome:180個
-
Safari:無限制
當Cookie數超過限制數時瀏覽器的行為:IE和Opera會采用LRU算法將老的不常使用的Cookie清除掉,Firefox的行為是隨機踢出某些Cookie的值。當然無論怎樣的策略,還是盡量不要讓Cookie數目超過瀏覽器所允許的范圍。
(2) 瀏覽器所允許的每個Cookie的最大長度
-
Firefox和Safari:4079字節
-
Opera:4096字節
-
IE:4095字節
(3) 服務器中Http請求頭長度的限制。Cookie會被附在每次http請求頭中傳遞給服務器,因此還會受到服務器請求頭長度的影響。