概述
HTTP 是基于 TCP/IP 协议的一个应用层协议,是现代互联网的一个基础协议。规定了客户端与服务端之间的通信格式以及所占用的服务端口80(HTTPS是443)。
超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。
HTTP版本发展:
HTTP 0.9(1991)
-> HTTP 1.0(1992-1996)
-> HTTP 1.1(1997-1999)
-> HTTP 2(2012-2014)
HTTP 0.9
HTTP 0.9是第一个版本的HTTP协议,已过时。它的组成极其简单,只允许客户端发送GET这一种请求,且不支持请求头。由于没有协议头,造成了HTTP 0.9协议只支持一种内容,即纯文本。不过网页仍然支持用HTML语言格式化,同时无法插入图片。
HTTP 0.9具有典型的无状态性,每个事务独立进行处理,事务结束时就释放这个连接。由此可见,HTTP协议的无状态特点在其第一个版本0.9中已经成型。一次HTTP 0.9的传输首先要建立一个由客户端到Web服务器的TCP连接,由客户端发起一个请求,然后由Web服务器返回页面内容,然后连接会关闭。如果请求的页面不存在,也不会返回任何错误码。
HTTP 1.0
HTTP协议的第二个版本,第一个在通讯中指定版本号的HTTP协议版本,至今仍被广泛采用。相对于HTTP 0.9 增加了如下主要特性:
- 请求与响应支持头域(下文介绍);
- 响应对象以一个响应状态行开始;
- 响应对象不只限于超文本;
- 开始支持客户端通过POST方法向Web服务器提交数据,支持GET、HEAD、POST方法;
- (短连接)每一个请求建立一个TCP连接,请求完成后立马断开连接。这将会导致2个问题:连接无法复用,head of line blocking。连接无法复用会导致每次请求都经历三次握手和慢启动。三次握手在高延迟的场景下影响较明显,慢启动则对文件类请求影响较大。head of line blocking会导致带宽无法被充分利用,以及后续健康请求被阻塞。
HTTP 1.1
HTTP协议的第三个版本是HTTP 1.1,是目前使用最广泛的协议版本 。
HTTP 1.1引入了许多关键性能优化:keepalive连接,chunked编码传输,字节范围请求,请求流水线等。
keepalive连接
Persistent Connection(keepalive连接):允许HTTP设备在事务处理结束之后将TCP连接保持在打开的状态,以便未来的HTTP请求重用现在的连接,直到客户端或服务器端决定将其关闭为止。
在HTTP1.0中使用长连接需要添加请求头 Connection: Keep-Alive,而在HTTP 1.1 所有的连接默认都是长连接,除非特殊声明不支持( HTTP请求报文首部加上Connection: close )。服务器端按照FIFO原则来处理不同的Request。
chunked编码传输
该编码将实体分块传送并逐块标明长度,直到长度为0块表示传输结束,这在实体长度未知时特别有用(比如由数据库动态产生的数据)
字节范围请求
HTTP1.1支持传送内容的一部分。比方说,当客户端已经有内容的一部分,为了节省带宽,可以只向服务器请求一部分。该功能通过在请求消息中引入了range头域来实现,它允许只请求资源的某个部分。在响应消息中Content-Range头域声明了返回的这部分对象的偏移值和长度。如果服务器相应地返回了对象所请求范围的内容,则响应码206(Partial Content)
Pipelining
HTTP管线化是将多个HTTP要求(request)整批提交的技术,而在传送过程中不需先等待服务端的回应。管线化机制须通过永久连接(persistent connection)完成,仅HTTP/1.1支持此技术(HTTP/1.0不支持),并且只有GET和HEAD要求可以进行管线化,而POST则有所限制。此外,初次创建连接时也不应启动管线机制,因为对方(服务器)不一定支持HTTP/1.1版本的协议。
另外,HTTP 1.1还新增了如下特性:
- 请求消息和响应消息都支持Host头域:在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname)。但随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。因此,Host头的引入就很有必要了。
- 新增了一批Request method:HTTP1.1增加了OPTIONS,PUT, DELETE, TRACE, CONNECT方法。
- 缓存处理:HTTP/1.1在1.0的基础上加入了一些cache的新特性,引入了实体标签,一般被称为e-tags,新增更为强大的Cache-Control头。
HTTP 2.0
HTTP 2.0是下一代HTTP协议,目前应用还非常少。
HTTP 2.0主要特点有:
-
多路复用(二进制分帧)。HTTP 2.0最大的特点:不会改动HTTP 的语义,HTTP 方法、状态码、URI 及首部字段,等等这些核心概念上一如往常,却能致力于突破上一代标准的性能限制,改进传输性能,实现低延迟和高吞吐量。而之所以叫2.0,是在于新增的二进制分帧层。在二进制分帧层上, HTTP 2.0 会将所有传输的信息分割为更小的消息和帧,并对它们采用二进制格式的编码 ,其中HTTP1.x的首部信息会被封装到Headers帧,而我们的request body则封装到Data帧里面。
-
HTTP 2.0 通信都在一个连接上完成,这个连接可以承载任意数量的双向数据流。相应地,每个数据流以消息的形式发送,而消息由一或多个帧组成,这些帧可以乱序发送,然后再根据每个帧首部的流标识符重新组装。
-
头部压缩:当一个客户端向相同服务器请求许多资源时,像来自同一个网页的图像,将会有大量的请求看上去几乎同样的,这就需要压缩技术对付这种几乎相同的信息。
-
随时复位:HTTP1.1一个缺点是当HTTP信息有一定长度大小数据传输时,你不能方便地随时停止它,中断TCP连接的代价是昂贵的。使用HTTP2的RST_STREAM将能方便停止一个信息传输,启动新的信息,在不中断连接的情况下提高带宽利用效率。
-
服务器端推流:Server Push。客户端请求一个资源X,服务器端判断也许客户端还需要资源Z,在无需事先询问客户端情况下将资源Z推送到客户端,客户端接受到后,可以缓存起来以备后用。
-
优先权和依赖:每个流都有自己的优先级别,会表明哪个流是最重要的,客户端会指定哪个流是最重要的,有一些依赖参数,这样一个流可以依赖另外一个流。优先级别可以在运行时动态改变,当用户滚动页面时,可以告诉浏览器哪个图像是最重要的,你也可以在一组流中进行优先筛选,能够突然抓住重点流。
HTTP头域
Requests部分
名称 | 说明 | 版本 |
---|---|---|
Accept | 指定客户端能够接收的内容类型 Accept: text/plain, text/html | |
Accept | 指定客户端能够接收的内容类型 Accept: text/plain, text/html | |
Accept-Charset | 浏览器可以接受的字符编码集。 Accept-Charset: iso-8859-5 | |
Accept-Encoding | 指定浏览器可以支持的web服务器返回内容压缩编码类型。 Accept-Encoding: compress, gzip | |
Accept-Language | 浏览器可接受的语言 Accept-Language: en,zh | |
Accept-Ranges | 可以请求网页实体的一个或者多个子范围字段 Accept-Ranges: bytes | |
Authorization | HTTP授权的授权证书 Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== | |
Cache-Control | 指定请求和响应遵循的缓存机制 Cache-Control: no-cache | |
Connection | 表示是否需要持久连接。(HTTP 1.1默认进行持久连接) Connection: close | |
Cookie | HTTP请求发送时,会把保存在该请求域名下的所有cookie值一起发送给web服务器。 Cookie: $Version=1; Skin=new; | |
Content-Length | 请求的内容长度 Content-Length: 348 | |
Content-Type | 请求的与实体对应的MIME信息 Content-Type: application/x-www-form-urlencoded | |
Date | 请求发送的日期和时间 Date: Tue, 15 Nov 2010 08:12:31 GMT | |
Expect | 请求的特定的服务器行为 Expect: 100-continue | |
From | 发出请求的用户的Email From: user@email.com | |
Host | 指定请求的服务器的域名和端口号 Host: | |
If-Match | 只有请求内容与实体相匹配才有效 If-Match: “737060cd8c284d8af7ad3082f209582d” | |
If-Modified-Since | 如果请求的部分在指定时间之后被修改则请求成功,未被修改则返回304代码 If-Modified-Since: Sat, 29 Oct 2010 19:43:31 GMT | |
If-None-Match | 如果内容未改变返回304代码,参数为服务器先前发送的Etag,与服务器回应的Etag比较判断是否改变 If-None-Match: “737060cd8c284d8af7ad3082f209582d” | |
If-Range | 如果实体未改变,服务器发送客户端丢失的部分,否则发送整个实体。参数也为Etag If-Range: “737060cd8c284d8af7ad3082f209582d” | |
If-Unmodified-Since | 只在实体在指定时间之后未被修改才请求成功 If-Unmodified-Since: Sat, 29 Oct 2010 19:43:31 GMT | |
Max-Forwards | 限制信息通过代理和网关传送的时间 Max-Forwards: 10 | |
Pragma | 用来包含实现特定的指令 Pragma: no-cache | |
Proxy-Authorization | 连接到代理的授权证书 Proxy-Authorization: Basic QWxhZGRpbjpvcGVuIHNlc2FtZQ== | |
Range | 只请求实体的一部分,指定范围 Range: bytes=500-999 | |
Referer | 先前网页的地址,当前请求网页紧随其后,即来路 Referer: http:///archives/71.html | |
TE | 客户端愿意接受的传输编码,并通知服务器接受接受尾加头信息 TE: trailers,deflate;q=0.5 | |
Upgrade | 向服务器指定某种传输协议以便服务器进行转换(如果支持) Upgrade: HTTP/2.0, SHTTP/1.3, IRC/6.9, RTA/x11 | |
User-Agent | User-Agent的内容包含发出请求的用户信息 User-Agent: Mozilla/5.0 (Linux; X11) | |
Via | 通知中间网关或代理服务器地址,通信协议 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) | |
Warning | 关于消息实体的警告信息 Warn: 199 Miscellaneous warning |
Responses 部分
名称 | 说明 | 版本 |
---|---|---|
Accept-Ranges | 表明服务器是否支持指定范围请求及哪种类型的分段请求 Accept-Ranges: bytes | |
Age | 从原始服务器到代理缓存形成的估算时间(以秒计,非负) Age: 12 | |
Allow | 对某网络资源的有效的请求行为,不允许则返回405 Allow: GET, HEAD | |
Cache-Control | 告诉所有的缓存机制是否可以缓存及哪种类型 Cache-Control: no-cache | |
Content-Encoding | web服务器支持的返回内容压缩编码类型。 Content-Encoding: gzip | |
Content-Language | 响应体的语言 Content-Language: en,zh | |
Content-Length | 响应体的长度 Content-Length: 348 | |
Content-Location | 请求资源可替代的备用的另一地址 Content-Location: /index.htm | |
Content-MD5 | 返回资源的MD5校验值 Content-MD5: Q2hlY2sgSW50ZWdyaXR5IQ== | |
Content-Range | 在整个返回体中本部分的字节位置 Content-Range: bytes 21010-47021/47022 | |
Content-Type | 返回内容的MIME类型 Content-Type: text/html; charset=utf-8 | |
Date | 原始服务器消息发出的时间 Date: Tue, 15 Nov 2010 08:12:31 GMT | |
ETag | 请求变量的实体标签的当前值 ETag: “737060cd8c284d8af7ad3082f209582d” | |
Expires | 响应过期的日期和时间 Expires: Thu, 01 Dec 2010 16:00:00 GMT | |
Last-Modified | 请求资源的最后修改时间 Last-Modified: Tue, 15 Nov 2010 12:45:26 GMT | |
Location | 用来重定向接收方到非请求URL的位置来完成请求或标识新的资源 Location: http:///archives/94.html | |
Pragma | 包括实现特定的指令,它可应用到响应链上的任何接收方 Pragma: no-cache | |
Proxy-Authenticate | 它指出认证方案和可应用到代理的该URL上的参数 Proxy-Authenticate: Basic | |
refresh | 应用于重定向或一个新的资源被创造,在5秒之后重定向(由网景提出,被大部分浏览器支持)Refresh: 5; url= | |
http:///archives/94.html | ||
Retry-After | 如果实体暂时不可取,通知客户端在指定时间之后再次尝试 Retry-After: 120 | |
Server | web服务器软件名称 Server: Apache/1.3.27 (Unix) (Red-Hat/Linux) | |
Set-Cookie | 设置Http Cookie Set-Cookie: UserID=JohnDoe; Max-Age=3600; Version=1 | |
Trailer | 指出头域在分块传输编码的尾部存在 Trailer: Max-Forwards | |
Transfer-Encoding | 文件传输编码 Transfer-Encoding:chunked | |
Vary | 告诉下游代理是使用缓存响应还是从原始服务器请求 Vary: * | |
Via | 告知代理客户端响应是通过哪里发送的 Via: 1.0 fred, 1.1 nowhere.com (Apache/1.1) | |
Warning | 警告实体可能存在的问题 Warning: 199 Miscellaneous warning | |
WWW-Authenticate | 表明客户端请求实体应该使用的授权方案 WWW-Authenticate: Basic |
HTTP 状态码
状态码 | 含义 |
---|---|
100 | 客户端应当继续发送请求。这个临时响应是用来通知客户端它的部分请求已经被服务器接收,且仍未被拒绝。客户端应当继续发送请求的剩余部分,或者如果请求已经完成 |
101 | 服务器已经理解了客户端的请求,并将通过Upgrade 消息头通知客户端采用不同的协议来完成这个请求。在发送完这个响应最后的空行后,服务器将会切换到在Upgrade |
102 | 由WebDAV(RFC 2518)扩展的状态码,代表处理将被继续执行。 |
200 | 请求已成功,请求所希望的响应头或数据体将随此响应返回。 |
201 | 请求已经被实现,而且有一个新的资源已经依据请求的需要而建立,且其 URI 已经随Location 头信息返回。假如需要的资源无法及时建立的话,应当返回 '202 |
202 | 服务器已接受请求,但尚未处理。正如它可能被拒绝一样,最终该请求可能会也可能不会被执行。在异步操作的场合下,没有比发送这个状态码更方便的做法了。 返回 |
203 | 服务器已成功处理了请求,但返回的实体头部元信息不是在原始服务器上有效的确定集合,而是来自本地或者第三方的拷贝。当前的信息可能是原始版本的子集或者超集。 |
204 | 服务器成功处理了请求,但不需要返回任何实体内容,并且希望返回更新了的元信息。响应可能通过实体头部的形式,返回新的或更新后的元信息。如果存在这些头部信息 |
205 | 服务器成功处理了请求,且没有返回任何内容。但是与204响应不同,返回此状态码的响应要求请求者重置文档视图。该响应主要是被用于接受用户输入后,立即重置表单, |
206 | 服务器已经成功处理了部分 GET 请求。类似于 FlashGet 或者迅雷这类的 HTTP 下载工具都是使用此类响应实现断点续传或者将一个大文档分解为多个下载段同时下载。 |
207 | 由WebDAV(RFC 2518)扩展的状态码,代表之后的消息体将是一个XML消息,并且可能依照之前子请求数量的不同,包含一系列独立的响应代码。 |
300 | 被请求的资源有一系列可供选择的回馈信息,每个都有自己特定的地址和浏览器驱动的商议信息。用户或浏览器能够自行选择一个首选的地址进行重定向。 |
301 | 被请求的资源已永久移动到新位置,并且将来任何对此资源的引用都应该使用本响应返回的若干个 URI |
302 | 请求的资源现在临时从不同的 URI |
303 | 对应当前请求的响应可以在另一个 URI 上被找到,而且客户端应当采用 GET |
304 | 如果客户端发送了一个带条件的 GET 请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个状态码。304响应 |
305 | 被请求的资源必须通过指定的代理才能被访问。Location 域中将给出指定的代理所在的 URI |
306 | 在最新版的规范中,306状态码已经不再被使用。 |
307 | 请求的资源现在临时从不同的URI |
400 | 1、语义有误,当前请求无法被服务器理解。除非进行修改,否则客户端不应该重复提交这个请求。 2、请求参数有误。 |
401 | 当前请求需要用户验证。该响应必须包含一个适用于被请求资源的 WWW-Authenticate 信息头用以询问用户信息。客户端可以重复提交一个包含恰当的 Authorization |
402 | 该状态码是为了将来可能的需求而预留的。 |
403 | 服务器已经理解请求,但是拒绝执行它。与401响应不同的是,身份验证并不能提供任何帮助,而且这个请求也不应该被重复提交。如果这不是一个 HEAD |
404 | 请求失败,请求所希望得到的资源未被在服务器上发现。没有信息能够告诉用户这个状况到底是暂时的还是永久的。假如服务器知道情况的话,应当使用410状态码来告知旧 |
405 | 请求行中指定的请求方法不能被用于请求相应的资源。该响应必须返回一个Allow 头信息用以表示出当前资源能够接受的请求方法的列表。 鉴于 PUT,DELETE |
406 | 请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。 除非这是一个 HEAD |
407 | 与401响应类似,只不过客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个 Proxy-Authenticate 用以进行身份询问。客户端可以返回一个 |
408 | 请求超时。客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改。 |
409 | 由于和被请求的资源的当前状态之间存在冲突,请求无法完成。这个代码只允许用在这样的情况下才能被使用:用户被认为能够解决冲突,并且会重新提交新的请求。该响 |
410 | 被请求的资源在服务器上已经不再可用,而且没有任何已知的转发地址。这样的状况应当被认为是永久性的。如果可能,拥有链接编辑功能的客户端应当在获得用户许可后 |
411 | 服务器拒绝在没有定义 Content-Length 头的情况下接受请求。在添加了表明请求消息体长度的有效 Content-Length 头之后,客户端可以再次提交该请求。 |
412 | 服务器在验证在请求的头字段中给出先决条件时,没能满足其中的一个或多个。这个状态码允许客户端在获取资源时在请求的元信息(请求头字段数据)中设置先决条件, |
413 | 服务器拒绝处理当前请求,因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围。此种情况下,服务器可以关闭连接以免客户端继续发送此请求。 |
414 | 请求的URI 长度超过了服务器能够解释的长度,因此服务器拒绝对该请求提供服务。这比较少见,通常的情况包括: |
415 | 对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。 |
416 | 如果请求中包含了 Range 请求头,并且 Range 中指定的任何数据范围都与当前资源的可用范围不重合,同时请求中又没有定义 If-Range |
417 | 在请求头 Expect 中指定的预期内容无法被服务器满足,或者这个服务器是一个代理服务器,它有明显的证据证明在当前路由的下一个节点上,Expect 的内容无法被满足。 |
421 | 从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围。通常,这里的IP地址指的是从服务器上看到的客户端地址(比如用户的网关或者代理服务器地 |
422 | 从当前客户端所在的IP地址到服务器的连接数超过了服务器许可的最大范围。通常,这里的IP地址指的是从服务器上看到的客户端地址(比如用户的网关或者代理服务器地 |
422 | 请求格式正确,但是由于含有语义错误,无法响应。(RFC 4918 WebDAV)423 Locked 当前资源被锁定。(RFC 4918 WebDAV) |
424 | 由于之前的某个请求发生的错误,导致当前请求失败,例如 PROPPATCH。(RFC 4918 WebDAV) |
425 | 在WebDav Advanced Collections 草案中定义,但是未出现在《WebDAV 顺序集协议》(RFC 3658)中。 |
426 | 客户端应当切换到TLS/1.0。(RFC 2817) |
449 | 由微软扩展,代表请求应当在执行完适当的操作后进行重试。 |
500 | 服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。一般来说,这个问题都会在服务器的程序码出错时出现。 |
501 | 服务器不支持当前请求所需要的某个功能。当服务器无法识别请求的方法,并且无法支持其对任何资源的请求。 |
502 | 作为网关或者代理工作的服务器尝试执行请求时,从上游服务器接收到无效的响应。 |
503 | 由于临时的服务器维护或者过载,服务器当前无法处理请求。这个状况是临时的,并且将在一段时间以后恢复。如果能够预计延迟时间,那么响应中可以包含一个 |
504 | 作为网关或者代理工作的服务器尝试执行请求时,未能及时从上游服务器(URI标识出的服务器,例如HTTP、FTP、LDAP)或者辅助服务器(例如DNS)收到响应。 |
505 | 服务器不支持,或者拒绝支持在请求中使用的 HTTP |
506 | 由《透明内容协商协议》(RFC |
507 | 服务器无法存储完成请求所必须的内容。这个状况被认为是临时的。WebDAV (RFC 4918) |
509 | 服务器达到带宽限制。这不是一个官方的状态码,但是仍被广泛使用。 |
510 | 获取资源所需要的策略并没有没满足。(RFC 2774) |