URI 的完整格式
URI 還有一個“真正”的完整形態,如下圖所示
URI 的創造者蒂姆·伯納斯 - 李也曾經私下承認
://
並非必要,當初有些“過於草率”了。
這個“真正”形態比基本形態多了兩部分。
第一個多出的部分是協議名之後、主機名之前的身份信息“user:passwd@”,表示登錄主機時的用戶名和密碼,但現在已經不推薦使用這種形式了(RFC7230),因爲它把敏感信息以明文形式暴露出來,存在嚴重的安全隱患。
第二個多出的部分是查詢參數後的片段標識符“#fragment”,它是 URI 所定位的資源內部的一個“錨點”或者說是“標籤”,瀏覽器可以在獲取資源後直接跳轉到它指示的位置。
但片段標識符僅能由瀏覽器這樣的客戶端使用,服務器是看不到的。也就是說,瀏覽器永遠不會把帶“#fragment”的
URI 發送給服務器,服務器也永遠不會用這種方式去處理資源的片段。
URI 的編碼
在 URI 裏只能使用 ASCII 碼,但如果要在 URI 裏使用英語以外的漢語、日語等其他語言該怎麼辦呢?
還有,某些特殊的 URI,會在 path、query 裏出現“@&?"等起界定符作用的字符,會導致 URI 解析錯誤,這時又該怎麼辦呢?
URI 轉義的規則有點“簡單粗暴”,直接把非 ASCII 碼或特殊字符轉換成十六進制字節值,然後前面再加上一個“%”。
例如,空格被轉義成“%20”,“?”被轉義成“%3F”。而中文、日文等則通常使用 UTF-8 編碼後再轉義,例
如“銀河”會被轉義成“%E9%93%B6%E6%B2%B3”。
有了這個編碼規則後,URI 就更加完美了,可以支持任意的字符集用任何語言來標記資源。
不過我們在瀏覽器的地址欄裏通常是不會看到這些轉義後的“亂碼”的,這實際上是瀏覽器一種“友好”表現,隱藏了 URI 編碼後的“醜陋一面”,不信你可以試試下面的這個URI。先在 Chrome 的地址欄裏輸入這個 query 裏含有中文的URI,然後點擊地址欄,把它再拷貝到其他的編輯器裏,它就會“現出原形”。
小結
- URI 是用來唯一標記服務器上資源的一個字符串,通常也稱爲 URL;
- URI 通常由 scheme、host:port、path 和 query 四個部分組成,有的可以省略;
- scheme 叫“方案名”或者“協議名”,表示資源應該使用哪種協議來訪問;
- “host:port”表示資源所在的主機名和端口號;
- path 標記資源所在的位置;
- query 表示對資源附加的額外要求;
- 在 URI 裏對“@&/”等特殊字符和漢字必須要做編碼,否則服務器收到 HTTP 報文後會無法正確處理。