URL是如何解析的

    URL就是我们天天使用的网址,英文全称叫做uniform resource locator,你可以把它理解成互联网上每个页面独一无二的名字.其实也不全是页面了,比如一些FTP下载资源,或者网页上的mailto链接,都是使用URL表示的.其实URL就相当于互联网字典上的索引,这些URL本来是一个个的孤岛,被一些资源整合的工具(比如搜索引擎)整合后,使得互联网得以连接,所有的links加起来,就是我们看到的互联网了.关于URL的解析其实也是一个很复杂而又麻烦的事情,可不像我们打开浏览器输入baidu.com然后回车得到一个输入框那么轻松.

   那么它到底复杂到哪了,我们慢慢了解吧...

 

   关于URL的语法一般是这样的:

   scheme://[login[:password]@](host_name|host_address)[:port][/hierarchical/path/to/resource[?search_string][#fragment_id]]

   我们一个一个看:

   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&#09;:alert(1);">javascript alert()</a>
</body>
</html>

&#09;在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 

posted @ 2014-11-16 22:50  jaw-crusher  阅读(2071)  评论(0编辑  收藏  举报