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