HTTP是Hyper Text Transfer Protocol(超文本传输协议)的缩写。它的发展是万维网协会(World Wide Web Consortium)和Internet工作小组IETF(Internet Engineering Task Force)合作的结果,(他们)最终发布了一系列的RFC,RFC 1945定义了HTTP/1.0版本。其中最著名的就是RFC 2616。RFC 2616定义了今天普遍使用的一个版本——HTTP/ 1.1。HTTP协议是用于从WWW服务器传输超文本到本地浏览器的传送协议。它可以使浏览器更加高效,使网络传输减少。它不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
下面简单介绍一下HTTP/1.0和HTTP/1.1两个版本之间的差异:
(1)建立连接方面:
HTTP/1.0 每次请求都需要建立新的TCP连接,连接不能复用。
HTTP/1.1 新的请求可以在上次请求建立的TCP连接之上发送,连接可以复用。优点是减少重复进行TCP三次握手的开销,提高效率。注意:在同一个TCP连接中,新的请求需要等上次请求收到响应后,才能发送。
(2)HOST域:
HTTP1.1在Request消息头里头多了一个Host域, HTTP1.0则没有这个域。可能HTTP1.0的时候认为,建立TCP连接的时候已经指定了IP地址,这个IP地址上只有一个host。
GET /pub/WWW/TheProject.html HTTP/1.1
Host: www.w3.org
(3)日期时间戳:
Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123
Sunday, 06-Nov-94 08:49:37 GMT ; RFC 850, obsoleted by RFC 1036
Sun Nov 6 08:49:37 1994 ; ANSI C's asctime() format
发送方向,HTTP1.0要求不能生成第三种asctime格式的date/time stamp;HTTP1.1则要求只生成RFC 1123(第一种)格式的date/time stamp。
(4)状态响应码:
HTTP1.1中状态响应码100 (Continue) 状态代码的使用,允许客户端在发request消息body之前先用request header试探一下server,看server要不要接收request body,再决定要不要发request body。客户端在Request头部中包含
Expect: 100-continue
Server看到之后呢如果回100 (Continue) 这个状态代码,客户端就继续发request body。另外在HTTP/1.1中还增加了101、203、205等等性状态响应码。
Method = "OPTIONS" ; Section 9.2
| "GET" ; Section 9.3
| "HEAD" ; Section 9.4
| "POST" ; Section 9.5
| "PUT" ; Section 9.6
| "DELETE" ; Section 9.7
| "TRACE" ; Section 9.8
| "CONNECT" ; Section 9.9
| extension-method
extension-method = token
HTTP是一个应用层协议,由请求和响应构成,是一个标准的C/S模型。HTTP协议通常承载于TCP协议之上,有时也承载于TLS或SSL协议层之上,这个时候,就成了我们常说的HTTPS。默认HTTP的端口号为80,HTTPS的端口号为443。
注意:
(1)HTTP协议永远都是客户端发起请求,服务器回送响应。这样就限制了使用HTTP协议,无法实现在客户端没有发起请求的时候,服务器将消息推送给客户端。
(2)HTTP协议是一个无状态的协议,同一个客户端的这次请求和上次请求是没有对应关系。
(1)连接:Connection
一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间。
在http1.1,request和reponse头中都有可能出现一个connection的头,此header的含义是当client和server通信时对于长链接如何进行处理。
在http1.1中,client和server都是默认对方支持长链接的, 如果client使用http1.1协议,但又不希望使用长链接,则需要在header中指明connection的值为close;如果server方也不想支持长链接,则在response中也需要明确说明connection的值为close。不论request还是response的header中包含了值为close的connection,都表明当前正在使用的tcp链接在当天请求处理完毕后会被断掉。以后client再进行新的请求时就必须创建新的tcp链接了。
(2)消息:Message
HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。
(3)请求:Request
一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标识符和协议的版本号。
(4)响应:Response
一个从服务器返回的信息包括HTTP协议的版本号、请求的状态(例如“成功”或“没找到”)和文档的MIME类型。
(5)资源:Resource
由URI标识的网络数据对象或服务。
(6)实体:Entity
数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息和实体的本身内容。
(7)客户机:Client
一个为发送请求目的而建立连接的应用程序。
(8)用户代理:UserAgent
初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具。
(9)服务器:Server
一个接受连接并对请求返回信息的应用程序。
(10)源服务器:Originserver
是一个给定资源可以在其上驻留或被创建的服务器。
(11)代理:Proxy
一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求。
(12)网关:Gateway
一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
(13)通道:Tunnel
是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。
(14)缓存:Cache
反应信息的局域存储。
一次HTTP操作称为一个事务,其工作过程可分为四步:
1)首先客户机与服务器需要建立连接。只要单击某个超级链接,HTTP的工作开始。
2)建立连接后,客户机发送一个请求给服务器,请求方式的格式为:统一资源标识符(URL)、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。
3)服务器接到请求后,给予相应的响应信息,其格式为一个状态行,包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
4)客户端接收服务器所返回的信息通过浏览器显示在用户的显示屏上,然后客户机与服务器断开连接。
如果在以上过程中的某一步出现错误,那么产生错误的信息将返回到客户端,有显示屏输出。对于用户来说,这些过程是由HTTP自己完成的,用户只要用鼠标点击,等待信息显示就可以了。
下面使用WireShark抓包工具进行分析,在客户端浏览器输入http://image.baidu.com/,抓包结果如下图:
TCP(传输控制协议,工作在传输层)三次握手建立连接的过程:
step1:Cilent向Server发送SYN,表示想发起一次TCP连接。我们假定这次的序列号是某个数值X ,初始的ack号为0:
Trust ->Target
SYN
SEQ:X
ACK:0
step2:Server产生SYN,ACK响应,并向请求方发送ACK, ACK的值为X+1,表示数据成功接收到,且告知下一次希望接收到字节的SEQ是X+1。同时, 服务方向请求方发送自己的SEQ, 我们假定它的序列号是某个数值Y:
Target -> Trust
SYN,ACK
SEQ:Y
ACK:X+1
step3: 请求方向服务方发送ACK,表示接收到服务方的回应。这次它的SEQ值为X+1,同时它的ACK值为Y+1,原理同上:
Trust ->Target
ACK
SEQ:X+1
ACK:Y+1
注意:因为一个SYN 将占用一个序号,所以要加1。完成这一步以后, 请求方与服务方之间的连接开放,数据可以进行传输了。
上图中,No.4的HTTP请求消息如下图所示:
HTTP请求消息格式:
其中,HTTP的请求方法包括如下几种:
从上面描述可以看出,Get是向服务器发索取数据的一种请求;而Post是向服务器提交数据的一种请求,要提交的数据位于信息头后面的实体中。GET与POST方法有以下区别:
(1) 在客户端,Get方式在通过URL提交数据,数据在URL中可以看到;POST方式,数据放置在HTML HEADER内提交。
(2) GET方式提交的数据最多只能有1024字节,而POST则没有此限制。
(3) 安全性问题。正如在(1)中提到,使用 Get 的时候,参数会显示在地址栏上,而 Post 不会。所以,如果这些数据是中文数据而且是非敏感数据,那么使用 get;如果用户输入的数据不是中文字符而且包含敏感数据,那么还是使用 post为好。
(4) 安全的和幂等的。所谓安全的意味着该操作用于获取信息而非修改信息。幂等的意味着对同一 URL 的多个请求应该返回同样的结果。完整的定义并不像看起来那样严格。换句话说,GET 请求一般不应产生副作用。从根本上讲,其目标是当用户打开一个链接时,她可以确信从自身的角度来看没有改变资源。比如,新闻站点的头版不断更新。虽然第二次请求会返回不同的一批新闻,该操作仍然被认为是安全的和幂等的,因为它总是返回当前的新闻。反之亦然。POST 请求就不那么轻松了。POST 表示可能改变服务器上的资源的请求。仍然以新闻站点为例,读者对文章的注解应该通过 POST 请求实现,因为在注解提交之后站点已经不同了(比方说文章下面出现一条注解)。
No.5的HTTP状态响应消息如下图所示:
HTTP响应消息格式:
http的状态响应码可以分为5类:
通用头与消息类型无关,既可以出现在请求消息中,也可以出现在响应消息中。
Connection: 指定连接参数,如Keep-Alive或close;
Date: 消息创建的日期、时间戳;
MIMIE-Version: 指出消息发送方正在使用的MIME版本;
Trailer:
Transfer-Encoding: 告诉消息接收方此消息的传输码;
Upgrade: 消息发送方希望使用的新版本或协议;
Via: 记录消息经过的中间节点,如proxy、gateway等;
Cache-Control: Cache控制,下面包含多个头域,例如
max-age:cache对象保持fresh的时间,超出这个时间时对象需要重新激活;
s-maxage:与max-age类似;
must-revalidate:对每次请求都必须重新激活,不使用fresh机制;
no-store:不允许该对象被缓存;
no-cache:与no-store类似;
Pragma: Cache-Control的另一个方式,它也有no-cache头域;
Client-IP: Client端IP地址;
From: Client端用户的Email地址;
Host: Server端hostname和端口号;
Referer:用户请求的来源URL,例如通过百度链接到一个政府网站,在访问这个政府网站时,百度就是这个Referer。
User-Agent: 提供Client端User-Agent(Browser)信息。
UA-OS: 提供Client端操作系统信息;
UA-CPU: 提供Client端CPU信息;
UA-Disp: 提供Client端显示器信息;
UA-Pixels: 提供Client端显示器的像素信息;
UA-Color: 提供Client端显示器的颜色信息;
Accept: 告诉Server能够发送哪些类型的资源;
Accept-Charset: 告诉Server能够发送哪些类型的字符集;
Accept-Encoding: 告诉Server能够发送哪些类型的编码;
Accept-Language: 告诉Server能够发送哪些类型的语言;
TE: 告诉Server能够采取哪些扩展传输码(extension transfer codings);
Authorization: 客户端的验证数据(登录用户名和密码);
Cookie:Cookies是服务器为了辨别用户身份、进行session跟踪,由Server生成,发送给User-Agent(一般是浏览器),浏览器会将Cookie的key/value保存到某个目录下的文本文件内,下次请求同一网站时就发送该Cookie给服务器(前提是浏览器设置为启用cookie)。
Cookie2:
Max-Forwards: 请求能够转发(经过proxy或者gateway)的最大次数;
Proxy-Authorization: 与Authorization类似;
Proxy-Connetion: 与Connetion类似;
Expect: 列出所请求服务器的行为;
If-Match: 实体标签(entity tag)匹配时,请求才有效;
If-None-Match: 与If-Match相反;
If-Modified-Since: 如果资源从某个时间点之后被修改过,就获取该资源;
If-Unmodified-Since: 与If-Modified-Since相反;
Range: 请求指定范围内的资源;
If-Range: 允许对指定范围内的资源进行条件请求。
Age: 响应时间;
Public: Server对其上面的资源能够支持的Method;
Retry-After: 找不到资源时的重试时间;
Server: Server应用程序的名称和版本;
Title: 资源标题;
Warning: 警告消息,比start-line中的reason phrase更丰富;
Accept-Ranges:服务器能够接受资源类型的范围
Vary:
Set-Cookie:发往Client的Cookie,用于用户身份识别;
Set-Cookie2:
WWW-Authenticate:要求用户输入用户名和密码进行身份验证;
Proxy-Authenticate:
Allow:这个资源支持哪些Method(如GET、POST等);
Location:服务器返回302 Redirect时,指定客户端需要重定向的地址;
Content-Base:
Content-Encoding:消息中实体内容的编码(如是否压缩);
Content-Language:实体内容匹配的语言;
Content-Type:实体内容的MIME类型,还可以指定支持的字符集charset,如Content-Type: text/html; charset=iso-8859-4。如果实体中包含了多个不同MIME类型的部分,可以使用下面的格式:
Content-Type: multipart/form-data; boundary=[abcdefghijklmnopqrstuvwxyz],其中,boundary 是指分隔不同部分的字符串。
Content-Length:实体内容的长度;它可以用来判断一个消息是否有残缺;此外,在长连接中,无法使用关闭连接的信息来判定消息是否传送完毕,这个时候就需要Content-Length提供的信息;
Content-Location:资源的位置;
Content-MD5:实体内容的校验和;
Content-Range:当传送的资源被分割成多个部分响应时,该头域指明了当前响应消息中的实体内容属于整体资源的哪个部分;
ETag: 资源的版本号,可以用来判断过期的cache对象是否需要重新激活;
Expires: cache对象的失效时间;
Last-Modified: 资源的最后修改时间;
Cache-Control:限定这个资源的缓存方法;
PS:
Web Resources:
MIME(Multipurpose Internet Mail Extensions),多功能Internet邮件扩充协议,Web Server会将它们发送的多媒体数据的类型告诉Browser。
URI(Uniform Resource Identifier),通用资源描述符,HTTP通过它来检索网络上的资源;
URL(Uniform Resource Locator),通用资源定位符,例如http://www.baidu.com/index.html就是一个URL。
URN(Uniform Resource Name),URN与资源的名字相关,而与位置无关。