在客户端(通常指浏览器)与服务器能够交互(客户端发起请求,服务器返回响应)之前,必须在这两者间建立一个 TCP 链接,
HTTP 仅在这条链接上发送和接收报文
建立一个连接需要三次握手,而终止一个连接要经过四次挥手
TCP连接的三次握手
第一次握手:客户端的应用进程主动打开,并向服务端发出请求报文段。其首部中:SYN=1,seq=x
第二次握手:服务器应用进程被动打开。若同意客户端的请求,则发回确认报文,其首部中:SYN=1,ACK=1,ack=x+1,seq=y
第三次握手:客户端收到确认报文之后,通知上层应用进程连接已建立,并向服务器发出确认报文,其首部:ACK=1,ack=y+1。当服务器收到客户端的确认报文之后,也通知其上层应用进程连接已建立
为什么需要三次握手
假设只有两次
客户端 发送第一个请求给 服务器,在某些网络节点滞留,未到达 服务器
客户端 没有接收到响应,重新发送一个请求给 服务器,服务器 接收到后返回确认给 客户端,此时 服务器 开启连接
当连接结束后,第一个请求延迟到达了 服务器,此时 服务器发送确认后 也会开启连接(客户端已经没有请求了,浪费服务器资源)
而有三次握手时,客户端不会向服务器的确认发出确认,由于服务器收不到确认,就知道客户并没有要求建立连接
HTTP/0.9
只有一个 get 命令
没有 header 等描述数据的信息
服务器发送完毕,就关闭 TCP 连接
HTTP/1.0
增加很多命令
增加 status code 和 header
HTTP/1.1
持久连接
1. 非持久连接:每个连接处理一个请求-响应事务。
2. 持久连接:每个连接可以处理多个请求-响应事务。
持久连接情况下,服务器发出响应后让TCP连接继续打开着。同一对客户/服务器之间的后续请求和响应可以通过这个连接发送
pipeline
默认情况下,HTTP 请求是按顺序发出的,下一个请求只有在当前请求收到应答过后才会被发出
流水线是在同一条长连接上发出连续的请求,而不用等待应答返回,按照request顺序返回response
增加 host 和其他一些命令
跨域
出于安全原因,浏览器限制从脚本内发起的跨域HTTP请求或跨域请求可以正常发起,但是返回结果被浏览器拦截了
HTTP 客户端没有跨域,发送的请求都有响应回来并输出