URL就是咱們每天使用的網址,英文全稱叫作uniform resource locator,你能夠把它理解成互聯網上每一個頁面獨一無二的名字.其實也不全是頁面了,好比一些FTP下載資源,或者網頁上的mailto連接,都是使用URL表示的.其實URL就至關於互聯網字典上的索引,這些URL原本是一個個的孤島,被一些資源整合的工具(好比搜索引擎)整合後,使得互聯網得以鏈接,全部的links加起來,就是咱們看到的互聯網了.關於URL的解析其實也是一個很複雜而又麻煩的事情,可不像咱們打開瀏覽器輸入baidu.com而後回車獲得一個輸入框那麼輕鬆.javascript
那麼它到底複雜到哪了,咱們慢慢了解吧...html
關於URL的語法通常是這樣的:java
scheme://[login[:password]@](host_name|host_address)[:port][/hierarchical/path/to/resource[?search_string][#fragment_id]]web
咱們一個一個看:chrome
scheme可不是那個滿屏幕小括號的編程語言,而是方案的意思,其實我認爲能夠理解成打開一個互聯網資源的方式,好比http和ftp就是不一樣的方式,經常使用的scheme包括http,https,ftp,mailto,javascript,file(通常是打開本地瀏覽器能夠打開的資源時使用的),chrome(Chrome瀏覽器特有的).scheme名稱後加一個冒號,標準寫法是在':'前只能出現[a-z][A-Z][0-1]+-.這些字符的,可是不少瀏覽器對於額外的字符也可以解釋,好比下面這樣的HTML代碼,對於Chrome也是能夠解析的:編程
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>scheme</title> </head> <body> <a href="http: www.baidu.com">baidu</a> <a href="javascript	:alert(1);">javascript alert()</a> </body> </html>
	在HTML中是TAB的轉移字符,能夠在free-formatter中轉義回來.瀏覽器
不過對於Firefox第二個彈窗代碼就無法使用了,它解釋成了file:///Users/zookeep/Desktop/web/javascript:alert%281%29;一個本地文件的相對路徑地址.服務器
對於Safarier,會把第一個URL解釋成http:%0A%0A//www.baidu.com其中的換行符變成了line feed就沒法打開百度了.編程語言
對於scheme,咱們試試file一個本地可執行文件hello.exe,發現它無法執行文件而是把它下載下來了,看來file方法只能打開瀏覽器能夠識別的格式的文件,好比html,PDF等。工具
而後就是兩個//,若是不寫的話又會怎樣:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>without //</title> </head> <body> <a href="http:baidu.com">baidu</a> <a href="./http:baidu.com">baidu</a> </body> </html>
第一個沒有指定目錄,會被解釋成和http://baidu.com同樣的URL,而加上./(表示當前目錄),則會被解釋成一個本地的目錄.
下面是[login[:password]@]用戶的認證信息,這個其實如今用處不大,幾乎沒人會讓用戶這樣驗證,都是表單驗證了.不過這個認證信息選項會讓一些URL看起來很猥瑣,咱們之後再看.
接下來是主機名或者主機IP地址,好比localhost,或者一個域名google.com或者一個IP:http://74.125.130.99(一樣是Google).不過這些常規的寫法你們都明白,那麼一些猥瑣的寫法能夠
是這樣的:
http://0x7f.1
http://017700000001
一樣都是localhost的表示,第一個是把點分十進制第一個127寫成16進制,其餘三個組成一個數字,第二個是把127.0.0.1每個十進制都轉爲8進制而後加個0表示八進制的IP.
對於Google地址 74.125.130.99咱們也能夠這樣寫:
>>> a = '74.125.130.99' >>> map(hex, map(int, a.split('.'))) ['0x4a', '0x7d', '0x82', '0x63'] >>> '.'.join(map(hex, map(int, a.split('.')))) '0x4a.0x7d.0x82.0x63'
一樣能夠獲得Google的頁面.
或者:
>>> '.'.join(map(oct, map(int, a.split('.')))) '0112.0175.0202.0143'
也能夠訪問到Google.
對於端口號卻是沒什麼能夠玩的,記住經常使用的http是80, https 是443就好了.
下一個是路徑和資源好比/home/user/index.html這樣的文件,不過如今不少都不顯示文件的後綴了,由於都是動態網站了...
下一個是查詢字符串,這個就頗有用了,好比使用taobao的時候你輸入的查詢內容就會被填充到query中,
好比taobao.com/search?q=html就能在taobao找到你要的寶貝了...
下一個是片斷ID,這個但是個好東西,不過注意它和服務器但是沒有交互的,只是會在當前頁面找到一片內容,由瀏覽器跳到那裏去,
更多的內容能夠參考 這裏.
好了,咱們基本上看完了URL的基本解析方式,那麼以下的URL到底會把你帶到哪裏:
http://qq.com&location=12306.com@evil.net http://a@b@c.com http://www.sina.com&id=123@0300.0250.01.01
ok,看第一個,這不就是qq嘛,好了,你把它輸入Chrome一看,跑到了evil.net什麼鳥玩意.
第二個,也許會是a@b@c.com,進去看看再說,不過偉大的Chrome把咱們帶到了c.com
第三個,估計是sina網吧...好吧,它把我帶到了個人路由器登陸頁上.這是什麼亂七八糟的?!
其實,URL的解釋是沒錯的,不過咱們忽視了登陸信息罷了,[login[:password]@]
第一個URL中,qq.com&location=12306都被當作了你訪問evil.net的用戶名了
一樣的a@b也被當成c.com的認證消息了,
第三個也是同樣,只不過把域名換成了一個IP地址,更加難以看出真實的hosts是誰.若是再用HTML轉義如下,估計就沒人能看清楚了,哈哈...
不過我發現,萬能的Chrome仍是能夠在你的地址欄中高亮出真實的網址:
只是通常狀況下你們都沒有注意到罷了.
好了,這個使人頭疼的URL解析算是差很少搞明白了.
參考: https://code.google.com/p/browsersec/wiki/Part1