1.url是什么?url(uniform resource locator)中文翻译为统一资源定位符,是internet上资源的地址,比如一个文本文件一张图片,一个视频。通过url我们可以知道网络资源的位置以及访问它的协议。url由互联网工程任务组织 url工作小组制定并成为一个互联网标准。
2.url一般语法,正如由许多不同的获取资源的方法一样,描述这些资源的位置也有多种方案。不同的协议有不同的 url语法,但是url的通用语法为其他协议建立新的方案提供了框架,一般而言url的编写方式如下:<scheme>:<scheme-specific-part> url包含特定的协议名称<scheme>后面是冒号,然后是字符串,该字符串的解释取决于不同协议的具体实现。
3.具体协议,internet有很多应用层的协议可以获取网络资源,其url的格式语法会有所不同。以下是常见的协议
ftp File Transfer protocolhttp Hypertext Transfer Protocolgopher The Gopher protocolmailto Electronic mail addressnews USENET newsnntp USENET news using NNTP accesstelnet Reference to interactive sessionswais Wide Area Information Serversfile Host-specific file namesprospero Prospero Directory Service
虽然url除协议外的其余部分的语法可能会因特定协议而有所不同,但涉及直接对internet上的指定主机使用基于ip的协议的url <scheme-specific-part> 拥有通用的语法://<user>:<password>@ <password> <port>和<url-path> 都是可选的,url协议特定部分以双斜杠 //开头,表明它符合通用internet协议语法。不同的组件遵循以下规则:user 一个可选的用户名。有些协议例如ftp允许指定用户名 password 一个可选的密码。如果存在,则在用户后面用冒号分割。
用户名和密码如果存在,后面跟着一个 @ 字符。在用户名和密码字段中,必须对字符 : @ / 进行编码。host 必选的网络主机名由合法的域名或者 IP 表示,其中合法的域名中一系列域标签由点号分隔,每个域标签以字母数字字符开头和结尾,中间可能还包含 – 字符,最右边的域标签永远不会以数字开头port 可选的端口号。大多数协议具有默认端口号,所以有时可以省略。端口号以十进制为单位,与主机用冒号分隔,如果省略了端口,冒号也是可以省略的。url-path 指定了资源在主机上的具体位置,其语法取决于所使用的协议。
HTTP(S) URL 在了解了 URL 基本概念以及基本组成结构后,下面重点讲解 HTTP URL 的语法
HTTP(S) 不允许使用用户名或密码,一个合法的 HTTP(S) URL 格式如下:
http(s)://<host>:<port>/<path>?<query>#<frag>
1.协议名:http 或 https 协议;
2.<host>:主机名。一个 URL 中,既可以使用域名也可以使用 IP 表示主机地址;
3.<port>:端口。主机名和端口之间使用冒号分隔。端口是可选的,如果省略将采用默认端口,http 默认端口是 80,https 默认端口 443;
4.<path>:资源路径。资源在网络主机上的路径,路径也是可选的,缺省访问默认资源;
5.<query>:查询参数。格式为 key=value,多个参数使用 & 分隔;参数也是可选的;
6.<frag>:片段。从 # 开始到最后,一般用于定位到资源内的一个片段,比如文档的一个章节;片段也是可选的。
http://www.aspxfans.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
观察示例,对照 HTTP URL 的格式,我们可以知道:
1.http 为协议;
2.www.aspxfans.com 为主机域名;
3.8080 为端口号;
4.news/index.asp 为资源路径;
5.boardID=5&ID=24618&page=1 为查询参数;
6.name 为资源内的一个片段。
5.HTTP(S) URL 特殊字符
: 协议与URL 实现部分以及主机名与端口号之间的分隔符/ 分隔目录和子目录& URL 中指定的参数间的分隔符= URL 中指定参数的值? 分隔实际的 URL 和参数# 表示书签+ 表示空格% 指定特殊字符
6.URL 编码
6.1 为什么需要对 URL 编码
URL 是一个字符序列,由数字、字母和特殊字符组成。对 URL 进行编码主要原因有如下几点:
ASCII无法表示的字符: URL只使用 ASCII 编码字符集中的可打印字符来编写,因此不可打印字符以及 ASCII 之外的字符如果出现在 URL 中,都需要进行编码;
不安全的字符:由于多种原因,有些字符可能是不安全的。比如空字符是不安全的,因为当 URL 被排版或接受文字处理程序处理时,重要的空格可能会消失,也可能会引入无关紧要的空格。字符 < 和 > 是不安全的,因为它们被用作自由文本中 URL 周围的分隔符。引号”用于在某些系统中分隔 URL。字符 # 不安全,应该总是被编码,因为它用于万维网和某些协议(如 HTTP(S))中片段/锚的分隔符。字符 % 不安全,因为它用于其他字符的编码。还有些字符也不安全,因为已知网关和其他传输代理有时会修改这样的字符,这些字符有:{ } | \ ^ ~ ` [ ]。
保留字符:许多 URL 方案将某些字符保留为一种特殊的含义:它们在 URL 的方案特定部分中的出现具有指定的语义。如果 URL 中出现了不表示其特殊含义的保留字符,则必须对保留字符进行编码。比如字符; / ? : @ = &是方案中可能保留的具有特殊含义的字符。因此只有字母和数字[0-9a-zA-Z]、具有特殊含义的保留字符以及非保留字符,才可以不经过编码直接用于 URL。
6.2 URL 编码规则
RFC3986 规定了 URL 中非保留字符,即无需转义的没有任何特殊含义的字符,其定义如下:
unreserved = ALPHA / DIGIT / “-” / “.” / “_” / “~”
ALPHA 表示 52 大小写英文字母,DIGIT 表示 10 个数字,后面依次是连字符、点号、下划线和波浪号。
除了上面非保留字符,其他任何字符出现在 URL 的不同部分时,如果与该部分的保留字符发生冲突或不可打印或超出 ASCII 表示范围,均需要对其编码。
6.3 URL 编码方式
URL 的编码方式也比较简单,即使用字符 % 后跟两个十六进制数字(0123456789ABCDEF 或 0123456789abcdef)表示字符码值的单个字节值。比如:
https://www.baidu.com/s?wd=春节
https://www.baidu.com/s?wd=%E6%98%A5%E8%8A%82
其中 0xE698A5 是汉字”春”的 UTF8 码值,0xE88A82 是汉字”节”的 UTF8 码值。
以 Go 为例,可以使用 url.QueryEscape 和 url.QueryUnescape 实现参数的编码和解码。