01 概述
HTTP(Hyper Text Transformer Protocol,超文本传输协议)是一种通信协议,它允许将超文本标记语言(HTML)文档从Web服务器传送到客户端的浏览器。
它是一个应用层协议,承载于TCP协议之上。
作用:
规定了应用进程间通信的准则
特点:
1、传输效率高
无连接:交换HTTP报文前,不需要建立HTTP连接
无状态:数据传输过程中,不保存任何历史和状态信息
传输格式简单:请求时,只需要传输请求方法和路径
2、传输可靠性高
采用TCP作为传输层协议
3、兼容性好
支持B/S、C/S模式
4、灵活性高
HTTP允许传输任意类型的数据对象
02 发展历史
作为Web文档传输协议的HTTP,版本更新十分缓慢,目前只更新了三个版本:
2.1 HTTP/0.9
定义GET方法拉取数据。
2.2 HTTP1.0
HTTP/1.0是第一个在通讯中指定版本号的HTTP协议版本,至今仍被广泛采用,特别是在代理服务器中。默认采用短连接。
在 HTTP 1.0 中, 没有官方的keepalive的操作。通常是在现有协议上添加一个指数。如果浏览器支持 keep-alive,它会在请求的包头中添加:Connection:Keep-Alive然后当服务器收到请求,作出回应的时候,它也添加一个头在响应中:Connection: Keep-Alive这样做,连接就不会中断,而是保持连接。当客户端发送另一个请求时,它会使用同一个连接。这一直继续到客户端或服务器端认为会话已经结束,其中一方中断连接。
HTTP1.0规定浏览器和服务器保持短暂的连接,浏览器的每次请求都需要与服务器建立一个TCP连接,服务器处理完成后立即断开TCP连接(无连接),服务器不跟踪每个客户端也不记录过去的请求(无状态)。这种无状态性可以借助cookie/session机制来做身份认证和状态记录。
而下面两个问题就比较麻烦:
首先,无连接的特性导致最大的性能缺陷就是无法复用连接。每次发送请求的时候,都需要进行一次TCP的连接,而TCP的连接释放过程又是比较费事的。这种无连接的特性会使得网络的利用率非常低。
其次就是队头阻塞(head of line blocking)。由于HTTP1.0规定下一个请求必须在前一个请求响应到达之前才能发送。假设前一个请求响应一直不到达,那么下一个请求就不发送,同样的后面的请求也给阻塞了。
为了解决这些问题,HTTP1.1出现了。
2.3 HTTP/1.1
HTTP/1.1版本,持久连接/长连接被默认采用(默认模式使用带流水线的持久连接),并能很好地配合代理服务器工作,还支持以管道方式同时发送多个请求,以便降低线路负载,提高传输速度。
注:HTTP1.0和1.1在之后很长的一段时间内会一直并存,这是由于网络基础设施更新缓慢所决定的。
HTTP持久连接不使用独立的keepalive信息,而是仅仅允许多个请求使用单个连接。
对于HTTP1.1,不仅继承了HTTP1.0简单的特点,还克服了诸多HTTP1.0性能上的问题。
首先是长连接,HTTP1.1增加了一个Connection字段,通过设置Keep-Alive可以保持HTTP连接不断开,避免了每次客户端与服务器请求都要重复建立释放建立TCP连接,提高了网络的利用率。如果客户端想关闭HTTP连接,可以在请求头中携带Connection: false来告知服务器关闭请求。
其次,是HTTP1.1支持请求管道化(pipelining)。基于HTTP1.1的长连接,使得请求管线化成为可能。管线化使得请求能够“并行”传输。
注意:这里的“并行”并不是真正意义上的并行传输,需要注意的是,服务器必须按照客户端请求的先后顺序依次回送相应的结果,以保证客户端能够区分出每次请求的响应内容。
也就是说,HTTP管道化可以让我们把先进先出队列从客户端(请求队列)迁移到服务端(响应队列)。
1、Keep-alive
优点:
较少的CPU和内存的使用(由于同时打开的连接的减少了)
允许请求和应答的HTTP管线化
减少了后续请求的延迟(无需再进行握手)
报告错误无需关闭
缺点:
对于单个文件被不断请求的服务(例如图片存放网站),Keep-Alive可能会极大的影响性能,因为它在文件被请求之后还保持了不必要的连接很长时间。
根据RFC2616,用户客户端与任何服务器和代理服务器之间不应该维持超过2个链接。代理服务器应该最多使用2×N个持久连接到其他服务器或代理服务器,其中N是同时活跃的用户数。这个指引旨在提高HTTP响应时间并避免阻塞。但由于,TCP连接减少了,对于静态资源(图片、JavaScript、CSS)较多的网站,性能反而可能会下降。
2、动静分离
为了规避上面说的对图片等静态资源的影响,大多数商业网站会启用独立的静态资源域名。从而保证主站的动态资源请求和静态资源的请求不会互相挤占连接。
动静分离同时还会有一个额外的好处:对于静态资源的请求,HTTP请求头里的Cookie等信息是没有用处的,反而占用了宝贵的上行网络资源。用独立的域名存放静态资源后,请求静态资源域名就不会默认带上主站域的Cookie,从而解决了这个问题。
2.4 HTTP2.0
HTTP/2.0在HTTP 1.x的基础上,大幅度的提高了web性能,减少了网络延迟。
HTTP2.0的几个特征:
1、多路复用
多路复用允许同时通过单一的HTTP/2连接发起多重的请求-响应消息。在 HTTP/1.1协议中浏览器客户端在同一时间,针对同一域名下的请求有一定数量限制。超过限制数目的请求会被阻塞。这也是为何一些站点会有多个静态资源CDN域名的原因之一,拿Twitter 为例,http://twimg.com,目的就是变相的解决浏览器针对同一域名的请求限制阻塞问题。而 HTTP/2的多路复用(Multiplexing) 则允许同时通过单一的HTTP/2连接发起多重的请求-响应消息。因此HTTP/2可以很容易的去实现多流并行而不用依赖建立多个TCP连接,HTTP/2把HTTP协议通信的基本单位缩小为一个一个的帧,这些帧对应着逻辑流中的消息。并行地在同一个TCP连接上双向交换消息。
2、二进制分帧
HTTP/2在应用层(HTTP/2)和传输层(TCP or UDP)之间增加一个二进制分帧层。在不改动 HTTP/1.x 的语义、方法、状态码、URI以及首部字段的情况下, 解决了HTTP1.1 的性能限制,改进传输性能,实现低延迟和高吞吐量。
在二进制分帧层中,HTTP/2会将所有传输的信息分割为更小的消息和帧(frame),并对它们采用二进制格式的编码,其中HTTP1.x 的首部信息会被封装到HEADER frame,而相应的Request Body 则封装到 DATA frame 里面。
3、首部压缩
HTTP/1.1并不支持 HTTP 首部压缩,为此SPDY和HTTP/2应运而生,SPDY使用的是通用的DEFLATE算法,而 HTTP/2则使用了专门为首部压缩而设计的HPACK算法。
在HTTP1.x中,头部元数据都是以纯文本的形式发送的,通常会给每个请求增加500~800字节的负荷。HTTP2.0使用encoder来减少需要传输的header大小,通讯双方各自cache一份header fields表,既避免了重复header的传输,又减小了需要传输的大小。高效的压缩算法可以很大的压缩header,减少发送包的数量从而降低延迟。
4、服务端推送
服务端推送是一种在客户端请求之前发送数据的机制。在 HTTP/2中,服务器可以对客户端的一个请求发送多个响应。Server Push让 HTTP1.x 时代使用内嵌资源的优化手段变得没有意义;如果一个请求是由你的主页发起的,服务器很可能会响应主页内容、logo 以及样式表,因为它知道客户端会用到这些东西。这相当于在一个 HTML 文档内集合了所有的资源,不过与之相比,服务器推送还有一个很大的优势:可以缓存!也让在遵循同源的情况下,不同页面之间可以共享缓存资源成为可能。
2.5 HTTP3.0
2013年Google开发了基于UDP的名为QUIC的传输层协议,QUIC全称Quick UDP Internet Connections,希望它能替代TCP,使得网页传输更加高效。后经提议,互联网工程任务组正式将基于QUIC协议的 HTTP(HTTP over QUIC)重命名为HTTP/3。
2.6 总结
HTTP1.0:
无状态、无连接
HTTP1.1:
持久连接
请求管道化
增加缓存处理
增加Host字段、支持断点传输等
HTTP2.0:
二进制分帧
多路复用(或连接共享)
头部压缩
服务器推送
03 URL与URI
URI:Uniform Resource Identifier,统一资源标识符;
URL:Uniform Resource Locator,统一资源定位符;
URN:Uniform Resource Name,统一资源名称。
注:URI是抽象的,URL和URN是具体的。
3.1 URI
URI(Uniform Resource Identifier),翻译为统一资源标识符,是一个用于标识某一互联网资源名称的字符串。
URI格式:
http://user:pass@www.example.com:80/home/index.html?age=11#mask
http:协议方案名
user:pass:登录信息(认证)
www.example.com:服务器地址
80:端口号
/home/index.html:文件路径
age=11:查询字符串
mask:片段标识符
3.2 URL
URL(Uniform Resource Location),翻译为统一资源定位符,它描述一台特定服务器上某特定资源的特定位置。
URI用字符串标识某一互联网资源,而URL表示资源的地点(资源所处的位置)。由此可见,URL是URI的子集。
URI由两个主要的子集URL(通过位置识别资源)和URN(通过名字识别资源)构成。
注:URN(Uniform Resource Name,统一资源名称)没有得到广泛应用。
URL格式:
<schema>://<user>:<password>@<host>:<port>/<path>;<param>?<query>#<frag>
schema协议方案名:http:、https:、ftp:等,在获取资源时要指定协议类型。
登录信息(认证):指定用户名和密码作为从服务器端获取资源时必要的登录信息,此项是可选的。
host服务器地址:使用绝对URI必须指定待访问的服务器地址。
port服务器端口号:指定服务器连接的端口号(用于一台主机上区分不同的服务),此项是可选的。
path路径:指定服务器上的文件路径来定位特定资源。
params参数:为应用程序提供访问资源所需的附加信息。
query查询字符串:传查询条件到服务器,来缩小请求资源范围,此项是可选的。
frag片段标识符:通常可标记出以获取资源中的子资源(文档内的某一个位置),此项是可选的。
04 HTTP请求方法
4.1 GET
请求指定的页面信息,并返回实体主体。
注:GET也可以将数据提交到服务器,不过一般都是使用POST提交数据到服务器。
4.2 POST
POST请求方法的作用:向服务器发送数据。
POST和GET请求方法的本质区别:
1、GET用于信息获取,它是安全的(这里安全的含义是指非修改信息),而POST是用于修改服务器上资源的请求;
2、GET请求的数据会附在URL之后(然后提交到服务器),而POST把提交的数据则放置在HTTP实体的主体里,所以,POST的安全性要比GET的安全性高;
3、GET方式提交数据和POST方法提交数据并没有限制数据大小。
4.3 HEAD
HEAD请求方法作用:只请求头部,允许客户端在未获取资源实体的情况下,对资源的头部检查,了解资源的基本情况,比如类型,是否被修改过等。
HEAD和GET请求方法的区别:GET请求回来的报文有实体的主体部分,而HEAD请求回来的报文没有实体的主体部分。
4.4 其他
PUT:向指定资源位置上传其最新内容。
DELETE:请求服务器删除指定的页面。
OPTIONS:返回服务器针对特定资源所支持的 HTTP 请求方法。
TRACE:回显服务器收到的请求,主要用于测试或诊断。
PATCH:实体中包含一个表,表中说明与该URI所表示的原内容的区别。
MOVE:请求服务器将指定的页面移至另一个网络地址。
COPY:请求服务器将指定的页面拷贝至另一个网络地址。
LINK:请求服务器建立链接关系。
UNLINK:断开链接关系。
WRAPPED:允许客户端发送经过封装的请求。
05 HTTP状态码
5.1 信息性状态码
100 Continue
说明收到了请求的初始部分,请客户端继续。发送了这个状态码之后,服务器在收到请求之后必须进行相应。
101 Switching Protocols
说明服务器正在根据客户端的指定,将协议切换成 Upgrade 首部所列的协议。
5.2 成功状态码
200 OK
请求成功,实体的主体部分包含了所请求的资源。
201 Created
表示服务器在请求的响应中建立了新的文档。
202 Accepted
请求已被接受,但服务器还未对其执行任何操作。
203 Non-Authoritative Information
请求已成功,但实体首部包含的信息不是来自于源服务器,而是来自本地或者第三方的一份副本。
204 No Content
服务器成功处理了请求,但没有返回任何内容(实体的主体部分)。
205 Reset Content
告知浏览器清除当前页面中所有HTML表单元素
206 Partial Content
成功执行了一个部分或者Range(范围)请求。
5.3 重定向错误状态码
300 Multiple Choices
表示被请求的文档可以在多个地方找到,并将在返回的文档中列出来。服务器可以在Location首部包含首选URL。
301 Moved Permanently
被请求的资源已永久移动到新位置,新的永久性的URL在响应的Location首部返回,并且会自动重定向到该URL去。
302 Found
与301状态码类似,只是Location首部所给的URL被理解为临时重定向,而不是永久重定向。
303 See Other
与301、302状态码类似,其主要目的是允许POST请求的响应将客户端定位到某个资源上去。
304 Not Modified
客户端发起一个GET请求,如果最近资源未被修改的话,就可以用这个状态码说明资源未被修改。
305 Use Proxy
被请求的资源必须通过指定的代理才能被访问。
307 Temporary Redirect
请求的资源现在临时从不同的URI 响应请求,与302状态码类似。
5.4 客户端错误状态码
400 Bad Request
用于告知客户端它发送了一个错误的请求。
401 Unauthorized
当前请求需要用户验证。
403 Forbidden
服务器已经理解请求,但是拒绝执行它。
404 Not Found
请求失败,请求所希望得到的资源未被在服务器上发现。
405 Method Not Allowed
指出请求方法对某些特定的资源不允许使用。
406 Not Acceptable
当前请求需要用户验证。
407 Proxy Authentication Required
该状态指出客户端必须通过代理服务器的认证。
408 Request Timeout
指服务端等待客户端发送请求的时间过长。
409 Conflict
该状态通常与PUT请求一同使用,常被用于试图上传版本不正确的文件时。
411 Length Required
服务器不能处理请求,除非客户端发送Content-Length头信息指出发送给服务器的数据的大小。
412 Precondition Failed
指出请求头信息中的某些先决条件是错误的。
413 Request Entity Too Large
告诉客户端现在所请求的文档比服务器现在想要处理的要大。
414 Request URI Too Long
请求的URL长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。
415 Unsupported Media Type
对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。
416 Requested Range Not Satisfiable
表示客户端包含了一个服务器无法满足的Range头信息的请求。
5.5 服务器错误状态码
500 Internal Server Error
服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。
501 Not Implemented
服务器不支持当前请求所需要的某个功能。
502 Bad Gateway
作为网关或者代理的服务器尝试执行请求时,从上游服务器接收到无效的响应。
503 Service Unavailable
由于临时的服务器维护或者过载,服务器当前无法处理请求。
504 Gateway Timeout
服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。
505 HTTP Version Not Supported
说服务器并不支持在请求中所标明 HTTP 版本。
06 HTTP报文
6.1 报文流
报文都是向下游流动的:
6.2 请求报文
请求报文的格式:
请求行:请求方法请求URL版本
首部:名:值
(空行)
实体的主体部分:(HTTP要传输的内容)
6.3 响应报文
响应报文的格式:
响应行:协议版本状态码原因短语
首部:名: 值
(空行)
实体的主体部分:(HTTP要传输的内容)
07 工作流程
7.1 域名解析
7.2 TCP三次握手
7.3 发起HTTP请求
经过三次握手建立TCP连接后,通过HTTP的GET/POST等方法发起HTTP请求。
7.4 服务器响应HTTP请求
服务端对客户端的HTTP请求进行解析,然后返回给客户端HTML。
7.5 浏览器解析HTML代码
浏览器拿到HTML文档后,开始解析HTML代码。
当遇到JS/CSS/图片等静态资源时,会自动向服务器端请求下载。
7.6 浏览器渲染页面返回用户
最后一步,浏览器利用自己内部的工作机制,把请求到的HTML代码和静态资源进行渲染,渲染最后,呈现给用户。
08 TCP与HTTP
HTTP 的长连接和短连接本质上是TCP 长连接和短连接。
HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。IP 协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。