繁體中文

開發者工具 · URL 編碼器和解碼器

從 RFC 1738 到 URL 標準:百分比編碼規則如何演變

· 背景

url 編碼 rfc 歷史記錄 網路標準

URL 百分比編碼標準從 RFC 1738 到 RFC 3986 到 WHATWG URL 標準的演變
原始 ToolAcre 向量圖

自 1994 以來,URL 中的轉義字元規則已被重寫多次。這篇文章遵循 RFC 1738、RFC 2396、RFC 3986 和 WHATWG URL 標準,並解釋了每次變更的內容。

從 RFC 1738 到 URL 標準 - 百分比編碼規則如何演變

波形符 (~) 舉例說明了編碼規則如何在標準產生和部署之間變更。 RFC 1738 (1994) 到處都需要 %7E; RFC 2396 (1998) 將波形符號移至未保留位置,允許未編碼。 RFC 3986 (2005) 確認未保留狀態。帶有 %7E 的舊 URL 仍然有效;新建設者輸出~。隨著網路的成熟和基礎設施的標準化,演變反映了部署的經驗教訓。 RFC 1738 是保守的,因為早期的基礎設施是異質且多樣的。

RFC 1738 編碼 1994 瀏覽器行為。在 UTF-8 上標準化部署;事實證明限制是不必要的。後來的標準放寬了字元限制。 RFC 3986 允許對非保留字元進行安全解碼。

RFC 1738 (1994):「不安全」字元和第一個轉義規則 - 什麼被認為是危險的以及為什麼

RFC 1738 將「不安全」字元定義為與 URI 語法(空格、斜線)衝突、歷史上在協定中使用的字元(控製字元)或系統無法安全傳輸的字元。保守的列表百分比編碼遠遠超出了現代互聯網的需要。許多早期系統早於 RFC;它規範了他們的行為。控製字元在協定中確實很危險;空格是 HTTP 用戶端從命令列讀取資料時的傳輸問題。現代系統透過顯式編碼更優雅地處理這些情況。

針對 RFC 1738 的測試揭示了舊系統的預期。對 20 世紀 90 年代 URL 規格中的字元進行編碼,並與現代 RFC 3986 進行比較。差異顯示了放鬆的情況。未保留的集合隨著時間的推移而擴大。連字號、句號、底線始終是安全的。蒂爾德需要 RFC 2396 才能變得安全。保守的方法意味著向後相容。根據 RFC 1738 規則建立的舊 URL 今天仍然有效。 RFC 3986 部分 6 中的規範化允許安全地解碼不必要的百分比編碼的非保留字元。

RFC 2396 (1998) — 保留與未保留、通用語法和復原的波形符

RFC 2396 (1998) 比 RFC 1738 更嚴格地闡明了字元集。它將服務於 URI 結構的保留字元與作為文字資料的非保留字元形式化。未保留的擴充包括連字符、句點、底線、波形符。它承認通用 URI 語法與特定於方案的規則分開。 RFC 2396 引入了 gen-delims (:, /, ?, #, [, ], @) 和子 delims (!, $, &, ', (, ), *, +, ,, ;, =) 之間的區別。命名明確了保留字元分為具有不同結構角色的兩組。

RFC 2396 引入了規範化指南,指定哪些百分比編碼字元可以在不改變含義的情況下進行解碼。未保留的字元解碼標準化。保留的字符編碼棒。 RFC 3986 進一步簡化了符號。標準強烈地保持向後相容性。

RFC 3986 (2005) — ! * ' ( ) 移動到 sub-delims,gen-delims 被命名,規範化指導到達

RFC 3986 (2005) 是百分比編碼的現代參考標準。它保留了保留的 /unreserved 區別,但簡化了符號並添加了規範化指導。蒂爾德毫不含糊地行動起來。標準澄清的百分比編碼的非保留字元可以在不改變含義的情況下進行解碼。 RFC 3986 部分 3 精確描述了 URI 語法。 2 節定義字元類別。 6 節專門用於句法規範化的正式規則。如果規範化形式匹配,基於比較的規範化會認為 URI 相同。從路徑中刪除點段會正常化,但不會有任何變化。

標準化對於分析、快取、連結追蹤很重要。僅十六進位數字大小寫不同的 URL(RFC 3986 偏好大寫)在實務上應該是相同的。規範化可防止重複的日誌條目和快取未命中。無論請求者的編碼偏好為何,以規範化 URL 為關鍵的快取都會提供內容。 RFC 3986 規範化指導使系統能夠做出一致的決策。但嚴格的執行會破壞目前網路上正常運作的 URL。

WHATWG URL 標準:解析瀏覽器實際接收的內容 — 編碼集、特殊方案與容錯

WHATWG URL 標準(2016–現在)是從瀏覽器體驗產生的,其 URL 不完全遵循 RFC 3986。瀏覽器面臨未編碼的空間、混合編碼和怪癖。 WHATWG 描述的是真實的瀏覽器解析,而不是理論語法。現實世界的瀏覽器已經制定了實用的規則來容忍空格、處理轉義字元、從格式錯誤的輸入中恢復。 RFC 3986 到達 2005 並定義了形式語法,但實踐中的瀏覽器已經略有不同。

WHATWG 定義了九個具有上下文特定規則的編碼集。路徑中的空格變成 %20; userinfo 中的斜線變成 %2F。瀏覽器對網頁應用較窄的標準。 RFC 3986 提供基準; WHATWG 以此為基礎。

工作範例:一個帶有波形符號、空格和非 ASCII 字元的 URL — 每代規則如何對其進行編碼

國際化網域使用 punycode 編碼(München 變成 xn--mnchen-3ya)。路徑和查詢仍然使用百分比編碼。網域部分使用punycode;路徑和查詢部分使用百分比編碼。各層不會混合或乾擾。

IDNA(應用程式中的國際化網域名稱)解決主機名稱問題。 Punycode 將非 ASCII 編碼為 ASCII 以實現 DNS 相容性。 xn-- 前綴表示 punycode 編碼。演演算法是確定性的:münchen 總是變成 xn--mnchen-3ya。非 ASCII 字元必須在 DNS 解析之前進行轉換。由於 DNS 限制和標籤限制,百分比編碼不適用於主機名稱。每種方法都能正確解決不同的問題。標準的單獨發展是有充分理由的。

這不包括什麼 - IRI 和國際化域名,它們有自己的歷史

選擇標準取決於上下文。為瀏覽器建立 URL?遵循 RFC 3986;瀏覽器應用 WHATWG。較舊的系統?測試實施。了解演化論可以防止混亂。

現代建構者應根據上下文遵循 RFC 3986 或 WHATWG。新舊 URL 共存,需要仔細考慮相容性。 URL 編碼器和解碼器始終遵循 RFC 3986,提供獨立於瀏覽器行為的固定參考。 WHATWG 在 RFC 基礎知識之外新增了特定於元件的編碼集。了解什麼時候發生了變化有助於理解系統為何不一致。使用這兩種標準測試您的 URL 可以揭示哪個標準在您的環境中進行控制。兩個標準都是正確的。

重點:了解您的程式碼遵循哪個規則手冊 — URL 編碼器和解碼器如何為您提供 RFC 3986 行為作為固定參考點

RFC 3986 規範化允許安全地解碼不必要的百分比編碼的非保留字元。 %41 規範化為 A。像 %2F 這樣的編碼保留字元永遠不會解碼;改變意義會破壞結構。標準機構大力維護向後相容性。修復問題需要全球範圍內的協調,幾十年後是不可能的。標準書籍不會追溯破壞網路。改變編碼決策會同時破壞數十億個現有系統。

百分比編碼經歷了三十年的精心演變:從 RFC 1738 到 RFC 2396 和 RFC 3986 到現代 WHATWG URL 標準。現代程式碼應遵循 RFC 3986 基準。具有較早編碼的舊 URL 仍然有效。測試往返可確保正確性和相容性。