HTTP协议详解 [TOC] #### 1. HTTP与SPDY协议 HTTP协议简单是来说就是一种基于应用层的通讯规范,双方要进行通讯,就要遵守的一种规范。HTTP协议从服务器传输超文本到本地浏览器,可以使浏览器更加高效。HTTP协议不仅保证了超文本文档的快速和安全的传输,还能确定文档中哪一部分先传输,或者哪些部分优先显示。 ##### 1.1 HTTP协议 HTTP协议是一个应用层的通信规范,由请求和响应构成,是一个客户端服务器模型。HTTP协议承载于TCP协议之上,有时也承载于SSL、TLS协议之上(SSL、TLS也承载于TCP),这时就变成了我们常说的HTTPS。HTTP协议的默认端口是80,HTTPS是443。 HTTP协议的模型就是由客户端发起请求,服务端回送响应。HTTP协议是一个无状态的协议,一个客户端的两次请求没有任何对应关系。这属于典型的一问一答式交互,这种方式很多不足,例如服务端主动向客户端push等。 ##### 1.2 SPDY协议 SPDY协议的出现主要是为了弥补HTTP协议的不足,SPDY协议支持流复用、主动发起请求、强制SSL传输等特性。SPDY协议是由google设计推广的一种协议,目前在最新版本的Chrome和火狐等浏览器中都可以使用。 #### 2. HTTP协议如何工作 浏览网页是HTTP协议的主要作用,但是并不是全部作用。例如腾讯QQ、迅雷等都有使用HTTP协议。HTTP的主工作流程主要分为以下4步。 ##### 2.1 建立连接 客户端与服务端建立连接。用户点击一个超链接,HTTP协议开始工作。 ##### 2.2 发起请求 客户端向服务端发起请求。请求内容格式如下: ``` 统一资源标识符(URL) HTTP协议版本号 请求MIME信息(包含权限修饰符、客户端信息等) ``` ##### 2.3 响应请求 服务端接收到请求处理完毕后向客户端回送响应,响应格式为: ``` 状态行(包含协议版本号,成功或失败的状态) MIME信息(包含服务器信息、响应实体等) ``` ##### 2.4 断开连接 客户端显示响应后连接断开。 #### 3. HTTP协议中的主要概念 ##### 3.1 连接 首先需要说明的是,三次握手和四次挥手不属于HTTP协议的部分,它们属于TCP协议,但是上文有讲到过:HTTP是基于TCP的应用层协议,所以,HTTP在连接和断开时也要经过三次握手和四次挥手的过程。 ###### 3.1.1 TCP三次握手 首先看一张图片 ![](https://www.hello-world.ren/usr/uploads/2019/03/3436644530.png) 1. 第一次握手 客户端向服务器发出连接报文,同时随机生成一个初始序列号,这时客户端处于同步已发送状态。TCP协议规定,SYN=1报文段中不能携带数据,但需要消耗一个序号。**这是三次握手的开始,表示客户端向想要和服务器建立连接**。 2. 第二次握手 服务器收到连接请求后如果同意连接,则会发出`ACK=1,SYN=1`,确认号是`ack=client_jsn+1`,同时为自己初始化一个序列号`server_jsn`。此时服务器进入`SYN-RCVD`(同步收到)状态,此阶段同样不能携带数据,也要消耗一个序号。**这是第二次握手,表示服务器已同意并准备好连接,询问客户端是否准备完成。** 3. 第三次握手 客户端收到确认后向服务端发出报文`ACK=1,ack=server_jsn+1`,**表示已准备好,此时连接建立完成。** ###### 3.1.2 TCP四次挥手 ![](https://www.hello-world.ren/usr/uploads/2019/03/1775907623.png) 1. 第一次挥手 客户端向服务端发送`FIN`报文,表示请求断开连接。**此时,客户端进入FIN-WAIT-1(终止等待1)状态。** 2. 第二次挥手 服务端收到FIN返回`ACK`表示已经确认。**此时服务端处于`CLOSE-WAIT`(关闭等待)状态,即服务器已经知道客户端没有数据要发送了,但是如果客户端又发送了数据服务端依然要接收。** 3. 第三次挥手 服务端发送`FIN`到客户端,表示已经关闭连接。**此时服务器进入`LAST-ACK`(最后确认)状态,等待客户端的确认。** 4. 第四次挥手 客户端发送`ACK`(确认)报文,注意此时TCP连接还没有释放,必须经过2∗∗MSL(最长报文段寿命)的时间后,当客户端撤销相应的TCB后,才进入CLOSED状态。 服务器只要收到了客户端发出的确认,立即进入CLOSED状态。同样,撤销TCB后,就结束了这次的TCP连接。可以看到,服务器结束TCP连接的时间要比客户端早一些。 ##### 3.2 请求 HTTP协议的请求中主要包含:`请求行、请求主体、请求正文`, 请求行以请求方法符开头,以空格分开,具体格式如下: ``` Method Request-URI HTTP-Version CRLF POST /index.php/action/login HTTP/1.1 ``` 上述格式参数说明 |参数|说明| |:--|:--| |Method|请求方法| |Request-URI|请求资源统一标识符| |HTTP-Version|协议版本号| |CRLF|一个回车和换行 CR和LF不可单独出现,仅可作为结尾| 请求方法说明(大写) |方法名|说明| |:--|:--| |GET|请求URI所标识的资源| |POST|在URI所标识的资源后附加资源| |DELETE|请求服务器删除URI所标识的资源| |PUT|请求服务器存储一个资源,使用URI作为标识| |HEAD|请求获取由URI所标识的资源的响应报头| |TRACE|请求服务器回送收到的请求信息,主要用于测试或诊断| |CONNECT|保留已备将来使用| |OPTIONS|请求查询服务器性能或者与URI所标识的资源相关的选项和需求| ##### 3.3 响应 在接收到客户端的请求后,服务端处理完成后对该请求回送响应。响应主要又状态行、响应报头、响应正文组成。 状态行的格式如下: ``` HTTP-Version Status-Code Reason-Phrase CRLF HTTP/1.1 302 Moved Temporarily ``` 上述格式参数说明 |参数|说明| |:--|:--| |HTTP-Version|协议版本号| |Status-Code|响应状态码| |Reason-Phrase|状态码的文本描述| |CRLF|一个回车和换行 CR和LF不可单独出现,仅可作为结尾| 响应状态码由三位数字组成,分别代表了不同含义,可取值如下: |可取值|说明| |:--|:--| |1xx|提示信息。请求已接收,正在处理| |2xx|成功。请求已被成功接收、理解、接收| |3xx|重定向。要完成的请求需要更进一步的操作| |4xx|客户端错误。请求有语法错误或者请求无法实现| |5xx|服务端错误。服务器未能实现合法的请求| 关于状态码还有更细的划分,本文不做赘述。 ##### 3.4 报头 HTTP消息报头主要包括普通报头、请求报头、响应报头、实体报头,报头的格式如下: ``` 名字+:+空格+值 Content-Length: 89 ``` ###### 3.4.1 普通报头 普通报头中有少数报头用于所有的请求和响应消息。但并不被用于传输实体,只用于传输消息,如缓存控制、连接控制等。 ###### 3.4.2 请求报头 请求报头允许客户端传输请求的附加信息和自身的信息,如UA头、Accept头等。 ###### 3.4.3 响应报头 响应报头用于服务器传输在状态行中不能传输的附加响应信息,以及服务器自身信息,和对所标识的资源的下一步的操作信息,如location等。 ###### 3.4.4 重要报头说明 |报头|说明| |:--|:--| |Connection|如何处理长连接。在HTTP 1.1协议中client和server都默认对方支持长链接。| |host|指定所请求的资源的Internet主机和端口信息。HTTP 1.1版本必须包含host头。| |User-Agent|发出请求的用户信息。| |Accept|客户端可接受的文件格式。| |Cookie|客户端向服务端传输的某些信息。| |Set-Cookie|服务端向客户端传输的信息。只能包含一个value值,且需要设置path等。| |Cache-Control|指定请求和响应遵循的缓存机制。| |Referer|客户端指定的URL的来源,常用于生成退链表等。| |Content-Lenth|内容长度(字节)。| |Content-Range|响应的资源范围。可在每次请求中标记请求范围,实现断点传输等功能。| |Accept-Encodeing|指定可接受的编码格式。| |自定义报头|可使用协议中未正式启用或其他报头。| 2019-03-24 PHP核心技术与最佳实践 展开评论