1 URL简介
在万维网(WWW)上,每个信息资源在网上都有唯一的地址,该地址就叫URL(Uniform Resource Locator,统一资源定位符),也就是指网络地址。
URL格式为: <协议>://<主机>:<端口>/<路径>。
2 URL结构
一个完整的URL结构:
scheme://login:password@address:port/path/to/resource?query_string#fragment
-
协议名称【schema】:
不区分大小写、以单个冒号结束。 -
层级URL的标记符号【//】:
为了兼容层级结构与非层级结构,标记//在与不在都会正常的解析;
非层级URL代表【mailto:协议】,标识为电子邮件地址,默认传递给邮件客户端程序。举例:
a.【http:example.com/】:当没有符合要求的基准URL环境(比如页面的base地址,图片地址为a.jpg,其实代表base/a.jpg)时,Firefox、Chrome、Safair认为是http://example,如果有基准URL环境,则认为是一个目录。
b.【javascript://example.com/%0alert(document.cookie)】:认为是一个有效的非层级伪URL并以javascript方式来执行alert(document.cookie)代码。
c.【mailto://user@example.com】层级URL标记符号会被忽略。 -
访问资源的身份验证【login:password@】:
可选项,若非需求,可以不填。如果没有提供身份验证信息,浏览器默认以匿名的方式获取数据,使用ftp协议时,则认为是一个ftp账号和一个假的密码 -
服务器地址【address】:
不区分大小写,支持域名、IPv4地址、IPv6地址。RFC只允许符合规范的IP地址写法,但大多数应用支持的比较灵活:
1、接受八进制、十进制(默认)和十六进制的写法;
2、接受把其中任意个 8位二进制加一起(a*256*256*256+b*256*256+c*256+d)再转成单个整数的写法例如:http://132.232.2.28/ = http://0x84.15204892/ = http://2229797404/
-
服务器端口【:port】:
每一种协议通常都会关联一个默认的服务端口(如HTTP为80,FTP为21) -
层级的文件路径【/path/to/resource】:
RFC表明,这个格式是直接从UNIX目录语义借用过来的,所以支持/…/和/./这种方式。 -
查询字符串【?query_string】:
用于把一串非层级格式的任意参数传递给前面路径所对应的资源。RFC文档中并没有硬性规定查询字符串的格式【name1=value1&name2=value2】这种格式是浏览器在处理HTML表单时生成的。 -
片段ID【#Fragment】:
用于客户端,指向HTML页面里的某个锚点名称,用于页面浏览定位,片段ID不会触发页面重载,可以用来存在一些临时数据用于节省开销,如记录地图的坐标
3 URL解析流程
-
提取协议名称:
寻找第一个冒号( : ),冒号前面的被认定为时协议名称,如果在冒号左边出现不应该出现的字符,则认为是相对URL。 -
去除层级URL标记符【//】:
如果没有发现该标记符,则可以忽视,若发现则跳过,出于可用性的考虑,URL标记符可以完全不用斜杠、一个或多个斜杠;考虑到windows使用反斜杠作为路径分隔符,大多数浏览器接收在URL任意位置使用反斜杠(\)替换斜杠(/),如:http:\example.com\index.php
-
获取授权信息部分:
依次扫描“/”或“\”、“?”、“#”符号,除去IE、Safari浏览器之外,老版本的其他浏览器还可以接受分号作为分隔符。截取扫描到的符号前面的字符串作为授权信息:A、定位登录信息:
在授权信息里面尝试寻找@符号,符号前面的部分认为是登录信息 在登录信息部分尝试寻找冒号( :),如果找到的话,冒号前面认为是用户名,后面则是密码。
B、提取目标地址:
除去授权信息部分,剩下的便认为是目标地址第一个冒号分隔开的认为是主机和端口 如果是方括号括起来的则认为是IPv6地址 -
确认路径:
依次扫描下一个“?”、“#”或者字符串结尾符,截取出来的便是路径部分 -
提取查询字符串:
依次扫描下一个“#”或者字符串结尾符,截取出来的便是查询字符串部分 -
提取片段ID:
其余部分均为片段ID部分
4 保留字符和URL编码
-
保留字符:
在URL中保留的字符包括 :/ ? # [ ] @ ! $ & ‘ ( ) * + , ; =在使用过程中保留字符会破坏语法,故使用时必须进行URL编码
-
URL编码:
即百分号编码,结构为:百分号(%)+对应字符ASCII值得十六进制形式
5 常见的URL协议及功能
-
浏览器本身支持、文档获取相关的协议:
由浏览器内部直接处理,通过特定的传输协议、获得指定文档的内容,并通过常规的内核解析引擎的逻辑处理,把文档最终呈现出来。例如:http、https、ftp、file、gopher(一种被淘汰的早起Web原型)、shttp(一个失败的https尝试,仅仅作为http的别名,IE支持)
-
由第三方应用和插件支持的协议:
浏览器会根据URL匹配情况,把具体的处理转给外部的某个应用程序。例如: 上文提到的mailto,电子邮箱地址,格式: mailto:
-
未封装的协议:
用于访问浏览器的脚本解析引擎和某些内部功能例如:javascript、livescript与mocha(早期javascript的别名)、data(用于创建一个短小的内置文档,可以通过继承而获得发起该URL页面的某些操作权限,格式为data:text/plain;base64,QW==)
-
封装过的协议:
可以放在任意URL之前,指示将取回的内容强制进行特殊的解码或者渲染显示例如:view-source(显示HTML页面的源代码)、jar(Firefox可以通过该协议解压类似ZIP的文件内容)、view-cache(Chrome浏览器访问缓存的方式)、wyciwyg(Firefox浏览器访问缓存的方式)
6 相对URL的类型
相对的URL类型一般分为5种:
- 有协议名,无授权信息
例如:http:angus.txt //通常会被当做一个相对地址
http:example.com //通常会被解析成绝对地址
- 无协议名,有授权信息
例如: //example.com //会继承原发起页面的协议名称
- 无协议名、授权信息,有路径
例如: ../notes.txt //典型的相对URL
- 无协议名、授权信息、路径,有查询字符串
例如: ?search=angus //引用原URL的协议、授权信息、路径信息
- 无协议名、授权信息、路径、查询字符串,有Fragment ID
例如: #angus //替换原URL片段ID部分。
山永远都在那,躲不开,只有持续的登高,然后,踩下它!
~~
怕山太高?怕自己能力不够?怕技术太深?一辈子怕下去?
~~
再复杂的技术,归根结底就是0 和 1,何惧哉!