url使用的編碼規則(認識url及其編碼)
2023-05-24 15:07:12 2
1.url是什麼?url(uniform resource locator)中文翻譯為統一資源定位符,是internet上資源的地址,比如一個文本文件一張圖片,一個視頻。通過url我們可以知道網絡資源的位置以及訪問它的協議。url由網際網路工程任務組織 url工作小組制定並成為一個網際網路標準。
2.url一般語法,正如由許多不同的獲取資源的方法一樣,描述這些資源的位置也有多種方案。不同的協議有不同的 url語法,但是url的通用語法為其他協議建立新的方案提供了框架,一般而言url的編寫方式如下:: url包含特定的協議名稱後面是冒號,然後是字符串,該字符串的解釋取決於不同協議的具體實現。
3.具體協議,internet有很多應用層的協議可以獲取網絡資源,其url的格式語法會有所不同。以下是常見的協議
ftp File Transfer protocolhttp Hypertext Transfer Protocolgopher The Gopher protocolmailto Electronic mail addressnews USENET newsnntp USENET news using NNTP accesstelnet Reference to interactive sessionswais Wide Area Information Serversfile Host-specific file namesprospero Prospero Directory Service
雖然url除協議外的其餘部分的語法可能會因特定協議而有所不同,但涉及直接對internet上的指定主機使用基於ip的協議的url 擁有通用的語法://:@ 和 都是可選的,url協議特定部分以雙斜槓 //開頭,表明它符合通用internet協議語法。不同的組件遵循以下規則:user 一個可選的用戶名。有些協議例如ftp允許指定用戶名 password 一個可選的密碼。如果存在,則在用戶後面用冒號分割。
用戶名和密碼如果存在,後面跟著一個 @ 字符。在用戶名和密碼欄位中,必須對字符 : @ / 進行編碼。host 必選的網絡主機名由合法的域名或者 IP 表示,其中合法的域名中一系列域標籤由點號分隔,每個域標籤以字母數字字符開頭和結尾,中間可能還包含 - 字符,最右邊的域標籤永遠不會以數字開頭port 可選的埠號。大多數協議具有默認埠號,所以有時可以省略。埠號以十進位為單位,與主機用冒號分隔,如果省略了埠,冒號也是可以省略的。url-path 指定了資源在主機上的具體位置,其語法取決於所使用的協議。
HTTP(S) URL 在了解了 URL 基本概念以及基本組成結構後,下面重點講解 HTTP URL 的語法
HTTP(S) 不允許使用用戶名或密碼,一個合法的 HTTP(S) URL 格式如下:
http(s)://:/?#
1.協議名:http 或 https 協議;
2.:主機名。一個 URL 中,既可以使用域名也可以使用 IP 表示主機地址;
3.:埠。主機名和埠之間使用冒號分隔。埠是可選的,如果省略將採用默認埠,http 默認埠是 80,https 默認埠 443;
4.:資源路徑。資源在網絡主機上的路徑,路徑也是可選的,預設訪問默認資源;
5.:查詢參數。格式為 key=value,多個參數使用 & 分隔;參數也是可選的;
6.:片段。從 # 開始到最後,一般用於定位到資源內的一個片段,比如文檔的一個章節;片段也是可選的。
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
觀察示例,對照 HTTP URL 的格式,我們可以知道:
1.http 為協議;
2.www.aspxfans.com 為主機域名;
3.8080 為埠號;
4.news/index.asp 為資源路徑;
5.boardID=5&ID=24618&page=1 為查詢參數;
6.name 為資源內的一個片段。
5.HTTP(S) URL 特殊字符
: 協議與URL 實現部分以及主機名與埠號之間的分隔符/ 分隔目錄和子目錄& URL 中指定的參數間的分隔符= URL 中指定參數的值? 分隔實際的 URL 和參數# 表示書籤 表示空格% 指定特殊字符
6.URL 編碼
6.1 為什麼需要對 URL 編碼
URL 是一個字符序列,由數字、字母和特殊字符組成。對 URL 進行編碼主要原因有如下幾點:
ASCII無法表示的字符: URL只使用 ASCII 編碼字符集中的可列印字符來編寫,因此不可列印字符以及 ASCII 之外的字符如果出現在 URL 中,都需要進行編碼;
不安全的字符:由於多種原因,有些字符可能是不安全的。比如空字符是不安全的,因為當 URL 被排版或接受文字處理程序處理時,重要的空格可能會消失,也可能會引入無關緊要的空格。字符 是不安全的,因為它們被用作自由文本中 URL 周圍的分隔符。引號"用於在某些系統中分隔 URL。字符 # 不安全,應該總是被編碼,因為它用於全球資訊網和某些協議(如 HTTP(S))中片段/錨的分隔符。字符 % 不安全,因為它用於其他字符的編碼。還有些字符也不安全,因為已知網關和其他傳輸代理有時會修改這樣的字符,這些字符有:{ } | \ ^ ~ ` [ ]。
保留字符:許多 URL 方案將某些字符保留為一種特殊的含義:它們在 URL 的方案特定部分中的出現具有指定的語義。如果 URL 中出現了不表示其特殊含義的保留字符,則必須對保留字符進行編碼。比如字符; / ? : @ = &是方案中可能保留的具有特殊含義的字符。因此只有字母和數字[0-9a-zA-Z]、具有特殊含義的保留字符以及非保留字符,才可以不經過編碼直接用於 URL。
6.2 URL 編碼規則
RFC3986 規定了 URL 中非保留字符,即無需轉義的沒有任何特殊含義的字符,其定義如下:
unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
ALPHA 表示 52 大小寫英文字母,DIGIT 表示 10 個數字,後面依次是連字符、點號、下劃線和波浪號。
除了上面非保留字符,其他任何字符出現在 URL 的不同部分時,如果與該部分的保留字符發生衝突或不可列印或超出 ASCII 表示範圍,均需要對其編碼。
6.3 URL 編碼方式
URL 的編碼方式也比較簡單,即使用字符 % 後跟兩個十六進位數字(0123456789ABCDEF 或 0123456789abcdef)表示字符碼值的單個字節值。比如:
https://www.baidu.com/s?wd=春節
https://www.baidu.com/s?wd=春節
其中 0xE698A5 是漢字"春"的 UTF8 碼值,0xE88A82 是漢字"節"的 UTF8 碼值。
以 Go 為例,可以使用 url.QueryEscape 和 url.QueryUnescape 實現參數的編碼和解碼。
package mainimport ( "net/url")func main { param := "春節" fmt.Println(url.QueryEscape(param)) fmt.Println(url.QueryUnescape(url.QueryEscape(param)))}
上面只是對 HTTP URL 的參數進行了編碼,如果 URL 中的路徑部分存在特殊字符,比如 / 或者 ?,也需要對其進行編碼,可以調用 Go 的 url.PathEscape 和 url.PathUnescape 來完成編解碼。