1. 什么是HTTP协议?
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。
RFC 1945定义了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定义了今天普遍使用的一个版本——HTTP 1.1。
简单地说,我们上网就是用户(客户端)遵循该协议向服务器发送请求获取资源,服务器解析该协议知道用户请求什么,然后把结果返回。
2. HTTP协议的内容?
HTTP是基于传输层的TCP协议,而TCP是一个端到端的面向连接的协议。所以HTTP在开始传输之前,首先需要建立TCP连接,而TCP连接的过程需要所谓的“三次握手”。下图所示TCP连接的三次握手。
在TCP三次握手之后,建立了TCP连接,此时HTTP就可以进行传输了。一个重要的概念是面向连接,既HTTP在传输完成之间并不断开TCP连接。在HTTP1.1中(通过Connection头设置 keep alive)这是默认行为。
简单地说,三次握手就是去小餐厅点菜,会先问我能点菜吗?可以,你确定要点餐吗?我确定要点餐。我要点吧啦吧啦……开始写菜单
2.1 客户端使用HTTP协议给服务器发送了什么?
HTTP请求由状态行、请求头、请求体三部分组成:
请求行:
①是请求方法,GET和POST是最常见的HTTP方法,除此以外还包括DELETE、HEAD、OPTIONS、PUT、TRACE、CONNECT,一共八种。
②为请求对应的URL地址,它和报文头的Host属性组成完整的请求URL。
③是协议名称及版本号。
请求头:
④是HTTP的报文头,报文头包含若干个属性,格式为“属性名:属性值”,服务端据此获取客户端的信息。
与缓存相关的规则信息,均包含在header中
请求体:
⑤是报文体,它将一个页面表单中的组件值通过param1=value1¶m2=value2的键值对形式编码成一个格式化串,它承载多个请求参数的数据。不但报文体可以传递请求参数,请求URL也可以通过类似于“/chapter15/user.html? param1=value1¶m2=value2”的方式传递请求参数。
简单来说,就是下菜单,点菜,写备注写要求。
2.2 服务器使用HTTP协议给客户端返回了什么?
HTTP的响应报文也由三部分组成,分别是响应行、响应头、响应体。
响应行:
①报文协议及版本;
②状态码及状态描述;
响应头:
③响应报文头,也是由多个属性组成;
响应体:
④响应报文体,即我们真正要的“干货”。
响应状态码:
和请求报文相比,响应报文多了一个“响应状态码”,它以“清晰明确”的语言告诉客户端本次请求的处理结果。
HTTP的响应状态码由5段组成:
(1)1xx 消息,一般是告诉客户端,请求已经收到了,正在处理,别急...
(2)2xx 处理成功,一般表示:请求收悉、我明白你要的、请求已受理、已经处理完成等信息。
(3)3xx 重定向到其它地方。它让客户端再发起一个请求以完成整个处理。
(4)4xx 处理发生错误,责任在客户端,如客户端的请求一个不存在的资源,客户端未被授权,禁止访问等。
(5)5xx 处理发生错误,责任在服务端,如服务端抛出异常,路由出错,HTTP版本不支持等。
常见的状态码:
200 OK 请求成功;
302 临时重定向
304 Not Modified 请求内容没有修改,使用本地缓存啦...
404 Not Found 请求的资源不存在
500 Internal Server Error 服务器错误
3. HTTP的无状态特点
根据早期的HTTP协议,每次请求响应时,都要重新建立TCP连接。TCP连接每次都重新建立,所以服务器无法知道上次请求和本次请求是否来自于同一个客户端。因此,HTTP通信是无状态(stateless)的。服务器认为每次请求都是一个全新的请求,无论该请求是否来自同一地址。
问题:为什么登录后就不用登录了?这不是记录的状态了吗?
答:HTTP并没有记录状态,而是程序,如PHP程序把状态保存在了cookie,session,不是HTTP记录了。
1. HTTP版本更替
HTTP/0.9
HTTP协议的最初版本,功能简陋,仅支持请求方式GET,并且仅能请求访问HTML格式的资源。
HTTP/1.0
在0.9版本上做了进步,增加了请求方式POST和HEAD;不再局限于0.9版本的HTML格式,根据Content-Type可以支持多种数据格式,即MIME多用途互联网邮件扩展,例如text/html、image/jpeg等;同时也开始支持cache,就是当客户端在规定时间内访问统一网站,直接访问cache即可。
但是1.0版本的工作方式是每次TCP连接只能发送一个请求,当服务器响应后就会关闭这次连接,下一个请求需要再次建立TCP连接,就是不支持keepalive。
HTTP/1.1
解决了1.0版本的keepalive问题,1.1版本加入了持久连接,一个TCP连接可以允许多个HTTP请求; 加入了管道机制,一个TCP连接同时允许多个请求同时发送,增加了并发性;新增了请求方式PUT、PATCH、DELETE等。
但是还存在一些问题,服务端是按队列顺序处理请求的,假如一个请求处理时间很长,则会导致后边的请求无法处理,这样就造成了队头阻塞的问题;同时HTTP是无状态的连接,因此每次请求都需要添加重复的字段,降低了带宽的利用率。
HTTP/2.0
为了解决1.1版本利用率不高的问题,提出了HTTP/2.0版本。增加双工模式,即不仅客户端能够同时发送多个请求,服务端也能同时处理多个请求,解决了队头堵塞的问题;HTTP请求和响应中,状态行和请求/响应头都是些信息字段,并没有真正的数据,因此在2.0版本中将所有的信息字段建立一张表,为表中的每个字段建立索引,客户端和服务端共同使用这个表,他们之间就以索引号来表示信息字段,这样就避免了1.0旧版本的重复繁琐的字段,并以压缩的方式传输,提高利用率。
另外也增加服务器推送的功能,即不经请求服务端主动向客户端发送数据,例如服务端可以主动把 JS 和 CSS 文件推送给客户端,而不需要客户端解析 HTML 再发送这些请求,当客户端需要的时候,它已经在客户端了。
当前主流的协议版本还是HTTP/1.1版本,既然HTTP/2.0这么好,为什么主流还是HTTP/1.1呢?
原因有很多:
(1)设备问题,以前的旧手机系统很多不支持。
(2)成本问题,HTTP/2.0开启https,就需要证书,购买证书需要花费。
(3)技术、运维成本,HTTPS部署相对HTTP来说麻烦好多。而且,如果正在使用HTTP,再转HTTP2,就可能需要替换时间成本。
(4)开发语言不支持,目前主流的开发语言,如C/C++,java,php等等都支持,但是有个别小众的语言应该还不支持。
(5)目前网站速度可以,不想更换。
(6)……