HTTP是一种能够获取如HTML这样网络资源的协议。它是Web上数据交换的基础,是一种client-server协议,也就是说请求通常是由浏览器这样的接受方发起的。一个完整的web文档是由不同的子文档重新组建而成的,像文本、样式、图片、视频、脚本等等。
HTTP基本性质
HTTP是简单的
即便在HTTP/2中把HTTP消息封装到了frames中,HTTP大体上还是被设计成可读的而且简单的。HTTP的消息能够让人读懂且明白它的意思,还允许简单的测试,放低了门槛,更有利于新来者了解。
HTTP是可扩展的
在HTTP/1中就出现了,HTTP headers让协议扩展变得非常容易。只要服务端和客户端在新的headers上语义达成一致,新的功能就可以轻松地被加进来。
HTTP是无状态的,有会话的
HTTP是无状态的:在同一个连接中,两个成功执行的请求之间是没有关系的。这就带来一个问题,用户没办法在一个网站进行连续的交互。通过cookie的使用可以解决这个问题,让用户的每次请求都能共享相同的上下文信息,相同的状态,从而创建有状态的会话。
HTTP和连接
一个连接是由传输层来控制的,基本不属于HTTP的范围内。然而HTTP并不需要下面的传输层的协议是面向连接的,它只需要它是可靠的,就是说不能丢失消息(至少没有错误)。在因特网两个最常用的传输层协议中,TCP是可靠的,而UDP不是。因此,HTTP依赖于TCP进行消息传递,虽然TCP是面向连接的,但这并不是必须的。
HTTP/1.0曾经为每一个请求/回应交换都打开一个TCP连接,但是TCP主要有两种流:打开一个连接需要多次的消息往返因此很慢。但是当多个消息周期性的发送时,这就变得更加高效:暖连接比冷连接更高效。
为了减少这些负担,HTTP/1.1引入流水线的概念(已被证明很难实现)和持久连接的概念:下层的TCP连接可以通过Connection头部来被部分地控制。HTTP/2则发展的更多,通过一个连接多个消息的方式来让这个连接始终保持为暖连接。
为了更好的适合HTTP,设计一种更好的传输层协议就一直在进行中。Google就研发了一种以UDP为基础,能提供更可靠更有效的传输层协议。
HTTP的扩展性举例
- 缓存。文档怎么缓存能够通过HTTP来控制。服务端能告诉代理和客户端什么需要被缓存,缓存多久,而客户端能够命令中间缓存代理来忽略存储的文档。
- 开放同源限制。HTTP可以通过修改头部来实现CORS(跨域资源共享)。
- 认证。一些页面能够被保护起来,仅让特定的用户进行访问。基本的认证功能可以直接通过HTTP提供,使用Authenticate相似的头部就可以,或者用HTTP cookie来设定指定的会话。
- 代理。服务端和客户端通常都处在内部网上,彼此的真实地址都是不可见的。HTTP请求就要通过代理穿过网络障碍。不是所有的代理都是HTTP代理的,像一些用SOCKS协议的代理就运作在更底层。
- 会话。Cookies用一个服务端的状态连接起了每一个请求。这就创建了会话,这很有用,不仅是因为能用到购物车这样的电商业务上,更是因为,它使得任何网站都能够配置页面展现的东西了。
一次HTTP请求过程
- 打开一个TCP连接(或者重用之前的一个)。
- 建立TCP连接之后,发送一个HTTP请求报文(request)。
- 读取服务端返回的报文(response)。
- 关闭连接或者为以后的请求重用连接。
HTTP请求报文
下面是一个HTTP请求报文的例子。
请求报文的元素由下面组成:
- method:GET或POST。
- path:获取资源的路径。
- version:HTTP协议的版本号。
- 对于一些像POST这样的方法,报文的body就包含了发送的资源,这个body和响应报文的body类似。
- 为服务端表达其它信息的可选择性的headers。
HTTP响应报文
下面是一个HTTP响应报文的例子。
响应报文的元素由下面组成:
- version:HTTP版本号。
- status code:表明对应的请求成功还是失败。
- status text:状态码对应的状态信息,可以由服务端自行设定。
- 其它的HTTP headers。
- 响应body。