前面提到,URL資源是HTTP協議所使用的尋找資源位置的定位符。分爲三個部分,主要的結構是:html
方案://服務器/路徑
這種結構使得網絡上的每個資源都只有惟一的命名方法,從而使得瀏覽器能夠統一對不一樣的資源進行處理,而不是依賴不一樣的軟件。
URL能夠從如下幾個部分去了解:算法
語法segmentfault
快捷方式數組
特殊字符瀏覽器
方案安全
最後,咱們還會展望將來,看看URN——URL的下一代。服務器
URL語法是跟對方案而變化的,可是這些變化老是創建在URL語法的9個組件組成的通用格式之上的。這個通用格式是:網絡
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?<query>#<frag>
這9個組件不須要所有包含,其中重要的三個部分是之間提到的:方案、主機 和 路徑。其可總結以下:app
方案 | 描述 | 默認值 |
---|---|---|
方案 | 使用的協議 | 無 |
用戶 | 某些方案訪問資源時要求的用戶名 | 匿名 |
密碼 | 在用戶名以後,中間以冒號:隔開 | <E-mail地址> |
主機 | 服務器的主機名或者點分IP地址(如192.168.1.1) | 無 |
端口 | 服務器監聽的端口,HTTP默認端口爲80 | 方案特有 |
路徑 | 服務器的資源本地名,路徑組件語法和服務器、方案相關 | 無 |
參數 | 使用該組件指定輸入參數。參數爲名/值對,用分號隔開 | 無 |
查詢 | 用於激活應用程序,沒有通用格式 | 無 |
片斷 | 部分資源名稱,引用時不會傳遞給服務器,只使用於客戶端內部。 | 無 |
方案
方案是規定如何訪問指定資源的主要標識符。要求以字母開始,用:隔開URL其他部分,且大小寫無關。編碼
主機和端口
主機標誌能訪問資源的服務器。主機可使用主機名或者IP地址來訪問;端口則標識服務器監聽的網絡端口,默認爲80。
用戶名和密碼
多用在FTP服務器上。若是URL方案要求提供用戶名和密碼,而用戶沒有輸入,則應用程序會插入一個默認的用戶名和密碼,隨瀏覽器而定
路徑
其說明資源在服務器中的位置,是服務器定位資源時須要的信息,用/將路徑劃分爲路徑段(path segment),路徑段還有各自的參數組件。
參數
服務器須要更多的信息,而不是簡單的主機名和路徑,而URL中的參數組件能夠提供更多的協議參數。該組件是名值對列表,每一個路徑段能夠有多個參數,形式相似:
http://www.baidu.com/pub/gnu;type=sb【並不存在,請勿當真】
這裏的路徑段gnu參數爲type,值爲sb。
查詢字符串
用於縮小請求資源類型範圍。如本專欄撰寫時,網址爲:
http://segmentfault.com/write?freshman=1
其中的freshman=1
就是查詢組件。我猜想,這個查詢組件的意思是:在服務器的write路徑中,是否一直保存着個人文章的草稿。查詢組件會發送給網關,由網關作進一步處理。若是須要多個名值對,則使用&字符進行分割。
片斷
HTML資源除了資源級,還能夠進一步劃分。好比指定文檔中的某個章節。而這個就可使用#<frag>
實現了。以本專欄的第一篇文章爲例,旁邊的文章目錄其實是在點擊之後,爲網址加上一個片斷,如#articleHeader6
實現的跳轉。這樣,瀏覽器能夠在得到整個資源之後,顯示你感興趣的部分。
這個快捷方式是針對客戶端的,能夠分爲相對URL和URL自動拓展。
前面提到的都是絕對URL,包含訪問資源所須要的所有信息。而相對URL則是不完整的,必須相對另外一個做爲基礎(base)的URL進行解析。這種便捷的縮略法爲寫網頁的人省了很多心。以下面的HTML代碼片斷:
<ul class="menu list-inline pull-left hidden-xs"> <li class="menu__item"><a href="/questions">問答</a></li> <li class="menu__item"><a href="/blogs">文章</a></li> <li class="menu__item"><a href="/user/note">筆記</a></li> <li class="menu__item"><a href="/jobs">職位</a></li> <li class="menu__item"><a href="/events">活動</a></li> </ul>
其中的問答、文章等超連接都是http://segmentfault.com/a/1190000004341687#articleHeader6
爲基礎URL,從而推導出方案和主機名。
因此,相對URL優點有二:
能夠保持HTML文檔的可讀性和書寫便捷。
能夠保持網頁上一組資源的便攜性。、
好比,能夠在搬移一組文檔時,保持連接的有效性。這樣,就能夠方便的搭載鏡像服務器了。
使用相對URL的步驟有二:一是找出基礎URL;二是解析相對引用。
找出基礎URL
基礎URL來源有二:一是網頁顯式指定,如在HTML網頁中,使用<BASE>標記指定基礎URL;二是隱式指定,封裝所屬資源的URL,咱們舉的例子即爲如此。
解析相對引用
對URL進行轉換,須要將相對URL和基礎URL劃分紅組件段,或者說「分解(decomposing)」。解析完URL後,能夠得到一個個組件,根據相對URL的完整程度,逐步對其進行填充,直到組合成新的絕對URL。這個填充是使用的是一個在RFC2396中定義的算法。
瀏覽器會爲用戶提供一條捷徑,使得用戶不須要輸入完整的URL,而交給瀏覽器填充。其方式有二:主機名拓展和歷史拓展。
主機名拓展
根據主機名進行拓展,找到匹配站點則構建成功;失敗則再次嘗試其餘可能。可是這種拓展可能會爲一些其餘HTTP應用程序(如代理)帶來問題。
歷史拓展
根據用戶訪問過的歷史URL進行拓展,該拓展經過選擇來完成。
爲了保障URL的可移植性(即便用任何因特網協議均可以安全傳輸)和完整性,URL須要:
使用通用的安全字母表
對不可見字符進行編碼以傳送
包含不安全的字符
爲了實現這點,URL使用了通用字母表,並增長了一些編碼規則。
URL中繼承了ASCII字符集和轉義序列,使得其可使用優先子集對任意字符值進行編碼。
經過「轉義」表示法,表示不安全字符。其包含一個百分號(%)和兩個表示字符ASCII碼的十六進制數。示例以下:
字符 | ASCII碼 | 示例URL |
---|---|---|
~ | 0x7E | http://www.joes-hardware.com/%7Ejoe |
(空格) | 0x20 | http://www.joes-hardware.com/more%20tools.html |
% | 0x25 | http://www.joes-hardware.com/100%25satisfaction.html |
在URL中,字符會由於有特殊含義、非ASCII可打印字符或者混淆協議和網關而被限制。下面是一些被限制的字符:
字符 | 保留/受限 |
---|---|
% | 保留爲轉義標誌 |
/?#:; | 保留爲定界符 |
. | 保留在路徑組件中使用 |
.. | 同上 |
$+ | 保留(不須要理由) |
@&= | 在不一樣的方案的上下文中有特殊含義,保留 |
{}[]~\^'| | 用於各類傳輸Agent代理,使用受限 |
<>" | 不安全,在URL範圍以外是有意義的,須要進行編碼 |
0x00-0x1F,0x7F | 受限,由於是不可打印字符 |
0x7F | 受限,由於不在US-ASCII字符集的7二進制位範圍以內 |
對於不安全字符,最好進行編碼。而判斷是否進行編碼則由從用戶處獲取URL的源端應用來作。URL中,可能有人故意對額外的字符進行編碼,從而繞過對URL進行模式匹配的應用。因此,解釋URL的應用必須在處理URL之間進行編碼。
下面是Web經常使用方案的一些格式:
方案 | 描述 |
---|---|
http | 超文本傳輸協議。沒有用戶名和密碼,除此以外符合通用URL,端口默認爲80. |
https | 與http相對使用了網景的SSL,爲HTTP提供端到端的加密機制,端口默認爲443 |
mailto | 指向E-mail地址。標準格式與URL格式不一樣,其語法記錄在RFC822中。 |
ftp | 文件傳輸協議、要求用戶名和密碼,能夠上傳、下載文件,並獲取其目錄結構內容 |
rtsp,rtspu | 經過實時流傳輸協議解析的多媒體資源標識符。除了方案部分,其他同上。 |
file | 表示一臺指定主機上能夠直接訪問的文件,省略主機名則默認爲本機 |
news | 由RFC036定義,訪問特定的文章或者新聞組。其自身包含的信息不足以對資源進行定位,其實際上與位置無關,只保留字符@來區分指向新聞組和指向新聞文章的URL |
telnet | 訪問交互式業務,表示能夠經過telnet訪問的交互式應用程序 |
實際上,因爲URL表示的實際的地址,因此在資源被移動之後,沒法定位對象。因此,下一代標準URN(統一資源名)開始研究,經過一個永久統一資源定位符PURL,使用URL實現URN的功能。能夠在PURL中獲取更多信息。
最後的彩蛋,猜猜這個是哪一個網頁的源代碼?
<!--[if lt IE 9]> <div class="alert alert-danger topframe" role="alert">你的瀏覽器實在<strong>太太太太太太舊了</strong>,放學別走,升級完瀏覽器再說 <a target="_blank" class="alert-link" href="http://browsehappy.com">當即升級</a> </div> <![endif]-->