關於「URL 長度限制」的傳說眾說紛紜:有人說是瀏覽器限制,有人說 HTTP 協議無限制,也有人說伺服器會攔截。本文透過實測數據與 RFC 規範,釐清各層面的真實邊界。
LimitRequestLine 預設 8190、Nginx large_client_header_buffers 預設 4k/8k、IIS maxUrlLength 預設 260/4096。作者實驗:Java 發送 GET 請求,Apache Module 回傳 strlen(r->args)。結果:
HTTP 414 Request-URI Too Long。| 層面 | 典型預設值 | 可調整性 | 備註 |
|---|---|---|---|
| IE / 老 Edge | 2,083 字元 | 不可調 | 歷史包袱 |
| Chrome / 新 Edge / Firefox | ~2 MB (2,097,152) | 不可調 | 實測可達 2MB 以上 |
| Safari | ~80 KB | 不可調 | 較保守 |
| Apache (LimitRequestLine) | 8,190 位元組 | httpd.conf 可改 | 含方法、URL、協議版本 |
| Nginx (large_client_header_buffers) | 4k/8k | nginx.conf 可改 | 單個 header 緩衝區大小 |
| IIS (maxUrlLength / maxQueryString) | 260 / 4096 | web.config 可改 | ASP.NET Core 另行配置 |
| CDN / WAF / Proxy | 不定(常 4k-8k) | 視廠商 | 隱形殺手,常被忽略 |
本質差異在於 傳輸載體:
GET /path?query HTTP/1.1),受限於第一行長度限制。Content-Length 或 Transfer-Encoding: chunked 分塊傳輸,不受 Request-Line 限制,理論上僅受 client_max_body_size、記憶體、磁碟配額約束。作者以 UDP 封包類比:GET 如單一封包,POST 可拆分多個封包傳輸再重組。
POST /search + JSON Body,或建立「查詢任務」返回 ID 輪詢。/users/123),過濾條件用 Query String,複雜查詢改 POST。理解各層限制來源,才能在架構設計時做出正確選型,避免上線後踩到「URL 過長」的隱形地雷。