HTTP简介
超文本传输协议是一个用于传输超媒体文档的应用层协议。它是为web浏览器与web服务器之间的通信而设计的,但也可以用于其他目的。HTTP遵循经典的客户端-服务端模型,客户端打开一个连接以发出请求,然后等待直到收到服务器端响应。HTTP是无状态协议,这意味着服务器不会在两个请求之间保留任何数据(状态)。尽管通常基于TCP/IP层,但它可以在任何可靠的传输层上使用,也就是说,该协议不会像UDP那样静默的丢掉信息。RUDP-作为UDP的可靠升级版本-是一种合适的替代选择。
一个完整的Web文档通常是由不同的子文档拼接而成的,像是文本,布局描述,图片,视频,脚本等等。客户端和服务端通过交换各自的消息(与数据流正好相反)进行交互。由像浏览器这样的客户端发出消息叫做request,被服务端响应的消息叫做response。
HTTP被设计于20世纪90年代初期,是一种可扩展的协议,它是应用层的协议,通过TCP,或者TLS-加密的TCP连接来发送,理论上任何可靠的传输协议都可以使用。因为其有良好的扩展性,时至今日,它不仅被用来传输超文本文档,还用来传输图片,视频或者向服务器发送HTML表单这样的信息。HTTP还可以根据网页需求,仅获取部分Web文档内容更新网页。
基本性质
1.HTTP是简单的:虽然下一代HTTP/2协议将HTTP消息封装到了帧中,HTTP大体上还是被设计得简单易读,HTTP报文能够被人读懂,还允许简单测试,降低了门槛,对新人很友好。
2.HTTP是扩展的:在HTTP/1.0中出现HTTP headers让协议扩展变得非常容易。只要服务端和客户端就新headers达成语义一致,新功能就可以被轻松加入进来。
3.HTTP是无状态,有会话的:HTTP 是无状态的:在同一个连接中,两个执行成功的请求之间是没有关系的。这就带来了一个问题,用户没有办法在同一个网站中进行连续的交互,比如在一个电商网站里,用户把某个商品加入到购物车,切换一个页面后再次添加了商品,这两次添加商品的请求之间没有关联,浏览器无法知道用户最终选择了哪些商品。而使用 HTTP 的头部扩展,HTTP Cookies 就可以解决这个问题。把 Cookies 添加到头部中,创建一个会话让每次请求都能共享相同的上下文信息,达成相同的状态。
注意,HTTP 本质是无状态的,使用 Cookies 可以创建有状态的会话
4.HTTP和连接:一个连接是由传输层来控制的,这从根本上不属于 HTTP 的范围。HTTP 并不需要其底层的传输层协议是面向连接的,只需要它是可靠的,或不丢失消息的(至少返回错误)。在互联网中,有两个最常用的传输层协议:TCP 是可靠的,而 UDP 不是。因此,HTTP 依赖于面向连接的 TCP 进行消息传递,但连接并不是必须的。在客户端(通常指浏览器)与服务器能够交互(客户端发起请求,服务器返回响应)之前,必须在这两者间建立一个 TCP 链接,打开一个 TCP 连接需要多次往返交换消息(因此耗时)。HTTP/1.0 默认为每一对 HTTP 请求/响应都打开一个单独的 TCP 连接。当需要连续发起多个请求时,这种模式比多个请求共享同一个 TCP 链接更低效。
为了减轻这些缺陷,HTTP/1.1引入了流水线和持久连接的概念:底层的TCP连接可以通过connection头部来被部分控制。HTTP/2则发展得更远,通过在一个连接复用消息得方式来让这个连接始终保持为暖连接。
为了更好的适合HTTP,设计一种更好传输协议的进程一直在进行。Google就研发了一种以UDP为基础,能提供更可可靠更高效的传输协议QUIC.
URI和URL
URI概念
URI就是由某个协议方案表示的资源的定位标识符,协议方案指的是访问资源所用的协议类型名称。
采用HTTP协议时,协议方案就是http,除此之外,还有ftp,mailto,telnet,file等。标准的URI协议有30种左右。
URI和URL的区别和联系
URI用字符串表示某一互联网资源,而URL表示资源的地点,即互联网上所处的位置。所以,URL是URI子集。
URI格式
表示指定的URI,要使用涵盖全部必要信息的绝对URI,绝对URL以及相对URL。相对URL,是指从浏览器中基本的URI处指定的URL。
一个绝对的URI大致由如下几部分构成:
使用http:或https:等协议方案名获取访问资源时要指定协议类型,不区分字母大小,最后附一个冒号。也可使用data:或javascript:这类指定数据或脚本程序的方案名。
一,协议方案名
http://
表示的是协议名称,表示请求时需要使用的协议,通常使用的是HTTP协议或安全协议HTTPS。HTTPS是以安全为目标的HTTP通道,在HTTP的基础上通过传输加密和身份认证保证了传输过程的安全性。
常见的应用层协议:
- DNS(Domain Name System)协议:域名系统。
- FTP(File Transfer Protocol)协议:文件传输协议。
- TELNET(Telnet)协议:远程终端协议。
- HTTP(Hyper Text Transfer Protocol)协议:超文本传输协议。
- HTTPS(Hyper Text Transfer Protocol over SecureSocket Layer)协议:安全数据传输协议。
- SMTP(Simple Mail Transfer Protocol)协议:电子邮件传输协议。
- POP3(Post Office Protocol - Version 3)协议:邮件读取协议。
- SNMP(Simple Network Management Protocol)协议:简单网络管理协议。‘
- TFTP(Trivial File Transfer Protocol)协议:简单文件传输协议。
二.登录信息
usr:pass
表示的是登录认证信息,包括登录用户的用户名和密码。虽然登录认证信息可以在URL中体现出来,但绝大多数URL的这个字段都是被省略的,因为登录信息可以通过其他方案交付给服务器。
三.服务器地址
www.example.jp表示的是服务器地址,也叫做域名,比如www.alibaba.com,www.qq.com,www.baidu,com
需要注意的是,我们用IP地址标识公网内的一台主机,但IP地址本身并不适合给用户看,比如说我们可以通过ping命令,分别获得www.baidu.com和www.qq.com这两个域名解析后的IP地址。
如果用户看到的是这IP地址,那么用户在访问这个网站之前并不知道这两个网站到底是干什么的,但如果用户看到的是www.baidu.com ,那么用户至少知道这两个网站分别对应的是哪家公司,因此域名具有更好的自描述性。
四.服务器端口号
80表示的是服务器端口号。HTTP协议和套接字编程一样都是位于应用层的,在进行套接字编程时我们需要给服务器绑定对应的IP和端口,而这里的应用层协议也同样需要有明确的端口号。
当我们使用某种协议时,该协议实际就是在为我们提供服务,现在这些常用的服务与端口号之间的对应关系都是明确的,所以我们在使用某种协议时实际是不需要指明该协议对应的端口号的,因此在URL当中,服务器的端口号一般也是被省略的。
五.带层次的文件路径
/dir/index.htm表示的是要访问的资源所在的路径。访问服务器的目的是获取服务器上的某种资源,通过前面的域名和端口已经能够找到对应的服务器进程了,此时要做的就是指明该资源所在的路径。
比如我们打开浏览器输入百度的域名后,此时浏览器就帮我们获取到了百度的首页。
当我们发起网页请求时,本质是获得了这样的一张网页信息,然后浏览器对这张网页信息进行解释,最后就呈现出了对应的网页。
我们可以将这种资源称为网页资源,此外我们还会向服务器请求视频、音频、网页、图片等资源。HTTP之所以叫做超文本传输协议,而不叫做文本传输协议,就是因为有很多资源实际并不是普通的文本资源。
因此在URL当中就有这样一个字段,用于表示要访问的资源所在的路径。此外我们可以看到,这里的路径分隔符是/,而不是\,这也就证明了实际很多服务都是部署在Linux上的。
六.查询字符串
uid=1表示的是请求时提供的额外的参数,这些参数是以键值对的形式,通过&符号分隔开的。
比如我们在百度上面搜索HTTP,此时可以看到URL中很多参数,而在这众多得参数当中有一个参数q,表示的就是我们搜索时的搜索关键字q=HTTP。
因此双方在进行网络通信时,是能够通过URL进行用户数据传送的。
七.片段标识符
ch1
表示的是片段标识符,是对资源的部分补充。
urlencode和urldecode
urlencode ()函数原理就是首先把中文字符转换为十六 进制 ,然后在每个字符前面加一个标识符%。 urldecode ()函数与urlencode ()函数原理相反,用于 解码 已编码的 URL 字符串,其原理就是把十六进制字符串转换为中文字符
如果在搜索关键字当中出现了像/?:
这样的字符,由于这些字符已经被URL当作特殊意义理解了,因此URL在呈现时会对这些特殊字符进行转义。
转义的规则如下:
- 将需要转码的字符转为十六进制,然后从右到左,取4位(不足4位直接处理),每两位做一位,前面加上%,编码成%XY格式。
示例
比如当我们搜索C++时,由于+
加号在URL当中也是特殊符号,而+
字符转为十六进制后的值就是0x2B
,因此一个+
就会被编码成一个%2B
。
说明一下: URL当中除了会对这些特殊符号做编码,对中文也会进行编码。
在线编码工具
这里分享一个在线编码工具:
选中其中的URL编码/解码模式,在输入C++后点击编码就能得到编码后的结果。
再点击解码就能得到原来输入的C++。
实际当服务器拿到对应的URL后,也需要对编码后的参数进行解码,此时服务器才能拿到你想要传递的参数,解码实际就是编码的逆过程。