HTTP
简介
HTTP协议(超文本传输协议HyperText Transfer Protocol),它是基于TCP协议的应用层传输协议,简单来说就是客户端和服务端进行数据传输的一种规则。

HTTP的五大特点
- 支持客户/服务器模式。
- 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
- 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。早期这么做的原因是请求资源少,追求快。后来通过Connection: Keep-Alive实现长连接
- 无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
网络基础与连接
HTTP通常运行在TCP之上。TCP/IP 协议族里重要的一点就是分层,TCP/IP 协议族按层次分别分为以下 4 层:应用层、传输层、网络层和数据链路层,而HTTP就属于其中的应用层。所谓分层便是根据每一层的协议在发送数据时对上层的数据进行包装,然后通过包装的数据找到接收者,在接受数据时再通过分层根据每一层的协议对数据进行解析得到原始数据。
各层作用:
应用层:应用层决定了向用户提供应用服务时通信的活动,即传输实际有用的内容。
传输层:在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Data Protocol,用户数据报协议)。HTTP使用的是TCP协议,通过此层的数据来建立连接,发送数据以及断开链接,以及验证数据包的完整性。
TCP部首中包含源端口和目标端口(用来区分发送和接收主机的应用程序)、序号(此时的数据会被分段,这里序号就是表示这个数据包是数据的第几段)以及校验和(用来检验数据包是否被损坏)。
网络层:网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所 起的作用就是在众多的选项内选择一条传输路线。
IP会装上自己的部首:源目IP地址,以及说明TCP一个下层协议的字段。IP数据包生成后他就可以被路由表转发啦。数据可以真正发送了。
数据链路层:用来处理连接网络的硬件部分。包括控制操作系统、硬件的设备驱 动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在 链路层的作用范围之内。
给IP包封装源目MAC地址,还有个字段会表示网络层是什么协议。这时候就会发送给对端。
其基本过程如下图:



HTTP连接
HTTP建立在TCP的基础上,每一次HTTP请求都会有一个连接和断开的过程,在TCP层次上便对应着TCP的三次握手和四次挥手。通过三次握手来确定连接然后发送数据,通过四次挥手将双方的数据接收发送完毕后断开连接完成请求。
三次握手

为什么要三次握手:

四次挥手

四次挥手的作用就是主动通知对方自己数据已发送完需要关闭发送通道,对方接受到后关闭己方的接收通道,双方接收发送通道都关闭后断开连接。
请求与响应
HTTP 协议和 TCP/IP 协议族内的其他众多的协议相同,用于客户端和 服务器之间的通信。 请求访问文本或图像等资源的一端称为客户端,而提供资源响应的一 端称为服务器端,用于 HTTP 协议交互的信息被称为 HTTP 报文。请求端(客户端)的 HTTP 报文叫做请求报文,响应端(服务器端)的叫做响应报文。 HTTP 报文本身是由多行(用 CR+LF 作换行符)数据构成的字符串文本。

请求和响应报文的基本结构如下图所示:


请求报文

请求行
请求行包含用于请求的方法,请求 URI 和 HTTP 版本
请求方法

URI
版本
相关介绍在文末
响应报文

状态行
请求行包含HTTP 版本、状态码和状态码描述
版本
相关介绍在文末
状态码 及 描述
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结 果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出 现了错误。
数字中的第一位指定了响应类别,后两位无分类。响应类别有以下 5 种:

常用状态码:
200 OK
表示从客户端发来的请求在服务器端被正常处理了
204 No Content
该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中 不含实体的主体部分。另外,也不允许返回任何实体的主体。比如, 当从浏览器发出请求处理后,返回 204 响应,那么浏览器显示的页面 不发生更新
206 Partial Content
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含由 Content-Range 指定范围的实体内容。
301 Moved Permanently
永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后 应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按 Location 首部字段提示的 URI 重新保存。
302 Found
临时性重定向。该状态码表示请求的资源已被分配了新的 URI,希望 用户(本次)能使用新的 URI 访问。 和 301 Moved Permanently 状态码相似,但 302 状态码代表的资源不 是被永久移动,只是临时性质的。换句话说,已移动的资源对应的 URI 将来还有可能发生改变。比如,用户把 URI 保存成书签,但不会 像 301 状态码出现时那样去更新书签,而是仍旧保留返回 302 状态码 的页面对应的 URI。
303 See Other
该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。 303 状态码和 302 Found 状态码有着相同的功能,但 303 状态码明确 表示客户端应当采用 GET 方法获取资源,这点与 302 状态码有区别。
比如,当使用 POST 方法访问 CGI 程序,其执行后的处理结果是希望 客户端能以 GET 方法重定向到另一个 URI 上去时,返回 303 状态 码。虽然 302 Found 状态码也可以实现相同的功能,但这里使用 303 状态码是最理想的。
当 301、302、303 响应状态码返回时,几乎所有的浏览器都会把 POST 改成 GET,并删除请求报文内的主体,之后请求会自动再次 发送。 301、302 标准是禁止将 POST 方法改变成 GET 方法的,但实际使 用时大家都会这么做。
304 Not Modified
该状态码表示客户端发送附带条件的请求时,服务器端允许请求访 问资源,但未满足条件的情况。304 状态码返回时,不包含任何响应 的主体部分。304 虽然被划分在 3XX 类别中,但是和重定向没有关 系。
与协商缓存相关。
307 Temporary Redirect
临时重定向。该状态码与 302 Found 有着相同的含义。尽管 302 标准禁止 POST 变换成 GET,但实际使用时大家并不遵守。
307 会遵照浏览器标准,不会从 POST 变成 GET。但是,对于处理响 应时的行为,每种浏览器有可能出现不同的情况。
400 Bad Request
该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求 的内容后再次发送请求。另外,浏览器会像 200 OK 一样对待该状态 码。
401 Unauthorized

该状态码表示发送的请求需要有通过 HTTP 认证(BASIC 认证、 DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示 用 户认证失败。
返回含有 401 的响应必须包含一个适用于被请求资源的 WWW- Authenticate 首部用以质询(challenge)用户信息。当浏览器初次接收 到 401 响应,会弹出认证用的对话窗口。
403 Forbidden
该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。
404 Not Found
该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服 务器端拒绝请求且不想说明理由时使用。
500 Internal Server Error
该状态码表明服务器端在执行请求时发生了错误。也有可能是 Web 应用存在的 bug 或某些临时的故障。
503 Service Unavailable
该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法 处理请求。如果事先得知解除以上状况需要的时间,最好写入 RetryAfter 首部字段再返回给客户端。
HTTP 首部
HTTP 首部字段是构成 HTTP 报文的要素之一。在客户端与服务器之 间以 HTTP 协议进行通信的过程中,无论是请求还是响应都会使用首 部字段,它能起到传递额外重要信息的作用。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的 语言、认证信息等内容。
首部类型
HTTP 首部字段根据实际用途被分为以下 4 种类型。
-
通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。
-
请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加 内容、客户端信息、响应内容相关优先级等信息。
-
响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加 内容,也会要求客户端附加额外的内容信息。
-
实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更 新时间等与实体有关的信息。
通用首部字段

请求首部字段

响应首部字段

实体首部字段

实体
作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。
实体主体
实体主体即是对文件、资源、字符等内容经过编码压缩生成的数据。与首部通过换行符隔开。


版本

http 0.9
- 只有一个请求行,并没有HTTP请求头和请求体。
- 服务器没有返回头信息,只返回数据信息。
- 第三个是返回的文件内容是以ASCII 字符流来传输的,只能传输HTML 格式的文件
http 1.0
- 协议版本信息会随着每个请求发送,即HTTP 1.0被追加到了GET行。
- 引入请求头,在发起请求时候会通过HTTP请求头告诉服务器它期待服务器返回什么类型的文件、采取什么形式的压缩、提供什么语言的文件以及文件的具体编码。
- 引入响应头,服务器以请求头中信息准备数据,并以响应头的信息告诉客户端数据采用何种格式返回,倘若遇到不支持的格式,只能返回服务器支持的格式,并在响应头中体现,也就是说最终浏览器是以响应头的信息解析数据。
- 引入状态码,状态码会在响应开始时发送,使浏览器能了解请求执行成功或失败,并相应调整行为。
- 引入了缓存机制,通过状态码与If-Modified-Since、Expires等控制更新或使用本地缓存。
- 引入了Content-Type头,使HTTP具备了传输除纯文本HTML文件以外其他类型文档的能力。
http 1.1
- 缓存处理,HTTP 1.1引入了更多的缓存控制策略,例如Entity tag、If-Unmodified-Since、If-Match、If-None-Match等更多可供选择的缓存头来控制缓存策略。
- 带宽优化以及网络连接的使用,在请求头中引入了range,它允许只请求资源的某一个部分,即返回206状态码,这样方便了开发者自由选择以便充分利用带宽和链接,并且可以使用Range和Content-Range制作断点续传功能。
- 错误通知的管理,在HTTP 1.1中新增了24个错误状态码。
- 增加Host请求头,能够使不同域名配置在同一个IP地址的服务器上。
- 支持长连接,HTTP 1.1支持长连接,在一个TCP连接上可以传输多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP 1.1中默认开启Connection:keep-alive,一般浏览器对于同一个域名允许同时建立6个长链接。
- 增加管线化技术,允许在第一个应答被完全发送之前就发送第二个请求,以改善队头阻塞问题,但响应的顺序还是会按照请求的顺序返回。
- 支持响应分块,通过设置Transfer-Encoding: chunked进行分块响应,允许响应的数据可以分成多个部分,配合服务端尽早释放缓冲可以获得更快的响应速度。
http 2.0
- 二进制分帧,HTTP 2.0是二进制协议而不是文本协议,将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码。
- 多路复用,并行的请求能在同一个链接中处理,在同一域名下所有访问都是从同一个TCP连接中走,HTTP消息被分解为独立的帧,服务端根据标识符和首部将消息重新组装起来,移除了HTTP 1.1中顺序和阻塞的约束。
- 压缩header,header在一系列请求中常常是相似的,其移除了重复和传输重复数据的成本。 服务端推送,服务器可以主动地向客户端推送资源,而无需客户端明确的请求。