The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

透過瀏覽器瀏覽網站時到底 URL 長度有沒有一定的限制

我們一般在規劃設計一個網站時,通常都不會特別考慮一個網頁的 URL 到底會有甚麼上限,因為一個正常人絕不會把網址設計的很長很長,對吧?但有時候我們希望把一些網頁的狀態保存在網址列上,方便用戶將網址加入書籤,下次回來時就可以看到原本的資料,這時就有可能會讓網址變的很長。這個問題每隔一段時間就會有學員提出,今天我想透過這篇文章跟大家說說這個 URL 的長度限制。

關於 URL 相關的文章,在我的部落格已經有不少文章,我特別整理如下,建議大家認真閱讀過:

  1. 講解 URL 網址結構與分享幾個相對路徑與絕對路徑的開發技巧
  2. 網頁開發人員應對 URL 的大小寫「有感覺」!
  3. 上傳檔案至 IIS 的檔案名稱有三個字元最好禁止使用: % # +
  4. 簡易克服 CSS 被瀏覽器快取(Cache)的問題
  5. 網站流量大時用 Session 太損耗記憶體,那要用什麼?
  6. 關於各瀏覽器對網頁與文字編碼的處理規則研究整理

你要瞭解一個 URL 的長度限制之前,最好瞭解一下,當你在瀏覽器輸入一個 URL 之後,到底會發生多少事?底下這張圖我之前在粉絲團分享過,得到非常多人的轉發,因為真的很多人不清楚原來從瀏覽器輸入網址之後,會發生這麼多事!

image

單就這篇文章的主題來說,你會需要知道兩個面向的限制:

  1. 瀏覽器端的限制

    瀏覽器名稱 預設 URL 最大長度限制 (Bytes)
    Google Chrome 2,097,152
    Microsoft Edge 2,097,152
    Mozilla Firefox 65,536
    Safari 80,000
    Opera Unlimited
  2. 伺服器端的限制

    Web 伺服器名稱 預設 URL
    最大長度限制
    參考資訊來源
    Apache Server (LimitRequestLine) 8,190 LimitRequestLine Directive
    Microsoft IIS (maxUrl) 4,096 Request Limits <requestLimits>
    Microsoft IIS (maxQueryString) 2,048 Request Limits <requestLimits>
    Nginx (large_client_header_buffers) 8,192 Module ngx_http_core_module

    從你的瀏覽器發出的 HTTP 封包,若 URL 長度超過 Web 伺服器的限制,預設會回傳 HTTP 414 URI Too Long 的錯誤回應。

關於這些前後端的限制

現在越來越多「純前端」的應用程式,許多瀏覽器上的 URL 其實都是虛擬的,就算網址列可以放這麼多字元,也不代表可以正確的送到後端,因為後端可以接受的 URL 長度限制通常比較低。

我相信很多人並不知道,原來 URL 的 fragment 片段 (#xxxx),其實是不會傳送到伺服器端的。所以你其實可以多多利用這個特性,把一些只需要儲存在前端的狀態保存在 fragment 之中。你可以嘗試一下 TypeScript Playground 網頁,這是一個可以讓你線上撰寫 TypeScript 的遊樂場,而且還具有 Share 功能,當你按下 Share 按鈕後,他會自動將所有寫好的程式碼,全部放到 URL 之中,他就是用 fragment 的方式保存程式碼的!

原本的網址長這樣:

https://www.typescriptlang.org/play

按下 Share 之後會變成這樣:

https://www.typescriptlang.org/play?#code/PTAEEkBdQWwSwO.... (很長的網址)

之後就可以將這個很長很長的網址傳給其他人,他們輸入這個很長很長的網址後,就可以看到跟你一樣的原始碼,是不是很酷! 👍

當然,保存狀態不是只有一種方法,除了可以放在 fragment 之外,你還可以選擇 localStorage, sessionStorage, Cookies, IndexedDB 等方法。這些不同的方法,各有不同的應用情境,你必須瞭解不同儲存方式的特性與細微差異,才有辦法分辨用哪一種比較適當。

綜觀上述的限制,我想無論如何都不會把 URL 的總長度設定超過 2,048 個字元 (不含 fragment 部分),如果真的要超過這個字數,你真的要好好考慮有沒有更好的設計方法,例如可以改用 HTTP POST 的方式傳輸參數,或是改用 localStorage 保存狀態等等。

相關連結