HTTP协议
什么是HTTP协议?
HTTP(Hyper Text Transfer Protocol)是一种可以获取网络资源(如文本,布局描述,图片,视频等)的一种传输协议;HTTP也是一种client-server协议,比如浏览器作为HTTP客户端可通过URL向HTTP服务端即Web服务器发送请求,Web服务器根据接收到的请求,向客户端发送响应信息。HTTP位于最上层的应用层,通过TCP或者TLS——安全的TCP连接来传送,理论上任何可靠的传输协议都可以使用。
HTTP组件系统
客户端 user-agent
user-agent 是任何能为用户发起行为的工具,通常是由浏览器来扮演,当然也有例外,比如调试应用程序。浏览器负责发HTTP请求,并进一步解析HTTP返回的消息,然后向用户以明确的响应。
Web服务端
上面提到的HTTP请求的另一端就是Web服务端,它是由Web Server来服务并提供客户端请求的资源,Server只是虚拟意义上代表一台机器,它可以是共享负载(负载均衡)的一组服务器组成的计算机集群,也可以是一种复杂的软件,通过向其他计算机(如缓存,数据库服务器,电子商务服务器...)发起请求来获取部分或全部资源。 Server 不一定是一台机器,一台机器上也可以装载许多的Server,在HTTP/1.1和host头部中,他们甚至可以共享一个IP地址。
代理Proxies
在客户端和服务端之间,有许多的计算机和其他设备参与转发HTTP消息。由于Web栈层次的原因,他们大部分分布在传输层,网络层和物理层上,他们对于HTTP来说是透明的,虽然它们可能会对应用层起到了很重要的作用。还有一部分是表现在应用层上的,称之为代理(Proxies),代理既可以表现的透明,也可以表现的不透明(改变请求会通过它们),代理有以下作用:
- 缓存(可以是公开的,也可以是私密的,比如浏览器缓存)
- 过滤(如反病毒扫描,家长控制)
- 负载均衡(让多个服务器服务不同的请求)
- 认证(对不同的资源进行权限管理)
- 日志控制(允许存储历史信息)
HTTP的基本属性
- HTTP是简单的
- HTTP是可扩展的
- HTTP是无序的,可会话的
- HTTP和连接
HTTP能控制什么
HTTP良好的可扩展性使得越来越多的Web功能归其控制,缓存和认证很早就可由HTTP进行控制,而同源限制直到2010年才得到改变。常见的可被HTTP控制的功能有:
- 缓存
- 开放同源限制
- 认证
- 代理和隧道
- 会话
HTTP流
客户端和服务端进行交互的过程表现如下:
- 打开一个TCP连接:TCP连接被用来发送一条或多条请求,以及接受响应消息。客户端可能打开一条新的连接,或重用一个已经存在的连接,或者也可能开几个新的TCP连接连向服务端
- 发送一个HTTP报文:HTTP报文(在HTTP/2之前)是语义可读的。在HTTP/2中,这些简单的消息被封装在了帧中,这使得报文不能被直接读取,但是原理仍是相同的。
- 读取服务端返回的报文
- 关闭TCP连接或者为后续请求重用连接。
HTTP报文
有两种HTTP报文的类型,请求与响应,每种都有其特定的格式。
请求
请求由以下元素组成:
- method,经常是由一个动词像GET, POST 或者一个名词像OPTIONS,HEAD来定义客户端的动作行为。通常客户端的操作都是获取资源(GET方法)或者发送HTML form表单值(POST方法),虽然在一些情况下也会有其他操作。
- 要获取的资源的路径,通常是上下文中就很明显的元素资源的URL,它没有协议protocol ,域名domain,或是TCP的端口号port(HTTP一般在80端口,https一般为443端口)。
- HTTP协议版本号。
- 为服务端表达其他信息的可选头部headers。
- 对于一些像POST这样的方法,报文的body就包含了发送的资源,这与响应报文的body类似。
响应
响应报文包含了下面的元素:
- HTTP协议版本号。
- 一个状态码(status code),来告知对应请求执行成功或失败,以及失败的原因。
- 一个状态信息,这个信息是非权威的状态码描述信息,可以由服务端自行设定。
- HTTP headers,与请求头部类似。
- 可选项,比起请求报文,响应报文中更常见地包含获取的资源body。
基于HTTP的APIs
最常见的就属XMLHttpRequest API了,可用于在user-agent和服务器之间交换数据。Fetch API提供相同的功能,且具有更强大和灵活的功能集。另一种API,即服务器发送的事件,是一种单向服务,允许服务器使用HTTP作为传输机制向客户端发送事件。使用EventSource接口,客户端打开连接并建立事件句柄。 客户端浏览器自动将到达HTTP流的消息转换为适当的Event对象,并将它们传递给专门处理这类type事件的句柄,如果有这么个句柄的话。但如果相应的事件处理句柄根本没有建立,那就交给onmessage事件处理程序处理。