HTTP通信机制是在一次完整的HTTP通信过程中,Web浏览器与Web服务器之间将完成下列7个步骤:
(1)建立TCP连接
在HTTP工作开始之前,Web浏览器首先要通过网络与Web服务器建立连接,该连接是通过TCP来完成的,该协议与IP协议共同构建Internet,即著名的TCP/IP协议族,因此Internet又被称作是TCP/IP网络。HTTP是比TCP更高层次的应用层协议,根据规则,只有低层协议建立之后才能,才能进行更层协议的连接,因此,首先要建立TCP连接,一般TCP连接的端口号是80
(2)Web浏览器向Web服务器发送请求命令<request-line>
一旦建立了TCP连接,Web浏览器就会向Web服务器发送请求命令
例如:GET/sample/hello.jsp HTTP/1.1
(3)Web浏览器发送请求头信息<headers>
浏览器发送其请求命令之后,还要以头信息的形式向Web服务器发送一些别的信息,之后浏览器发送了一空白行<blank line>来通知服务器,它已经结束了该头信息的发送
(4)Web服务器应答
客户机向服务器发出请求后,服务器会客户机回送应答,HTTP/1.1 200 OK,应答的第一部分是协议的版本号和应答状态码
(5)Web服务器发送应答头信息
正如客户端会随同请求发送关于自身的信息一样,服务器也会随同应答向用户发送关于它自己的数据及被请求的文档。
(6)Web服务器向浏览器发送数据
Web服务器向浏览器发送头信息后,它会发送一个空白行来表示头信息的发送到此为结束,接着,它就以Content-Type应答头信息所描述的格式发送用户所请求的实际数据
(7)Web服务器关闭TCP连接
一般情况下,一旦Web服务器向浏览器发送了请求数据,它就要关闭TCP连接,然后如果浏览器或者服务器在其头信息加入了这行代码Connection:keep-alive
TCP连接在发送后将仍然保持打开状态,于是,浏览器可以继续通过相同的连接发送请求。保持连接节省了为每个请求建立新连接所需的时间,还节约了网络带宽。
HTTP请求
HTTP请求的格式如下所示:
<request-line>
<headers>
<blank line>
[<request-body>]
在HTTP请求中,第一行必须是一个请求行(request line),用来说明请求类型(GET/POST)、要访问的资源,使用的HTTP版本(HTTP1.1等)。紧接着是一个首部(header)小节,用来说明服务器要使用的附加信息。在首部之后是一个空行,再此之后可以添加任意的其他数据[称之为主体(body)]。
HTTPGET请求:
在HTTP中,定义了多种请求类型,通常我们关心的只有GET请求和POST请求。只要在Web浏览器上输入一个URL,浏览器就将基于该URL向服务器发送一个GET请求,以告诉服务器获取并返回什么资源。对于www.baidu.com的GET请求如下所示:
GET / HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
请求行的第一部分说明了该请求是GET请求。该行的第二部分是一个斜杠(/),用来说明请求的是该域名的根目录。该行的最后一部分说明使用的是HTTP 1.1版本(另一个可选项是1.0)。那么请求发到哪里去呢?这就是第二行的内容。
第2行是请求的第一个首部,HOST。首部HOST将指出请求的目的地。结合HOST和上一行中的斜杠(/),可以通知服务器请求的是www.baidu.com/(HTTP 1.1才需要使用首部HOST,而原来的1.0版本则不需要使用)。第三行中包含的是首部User-Agent,服务器端和客户端脚本都能够访问它,它是浏览器类型检测逻辑的重要基础。 该信息由你使用的浏览器来定义(在本例中是Firefox 1.0.1),并且在每个请求中将自动发送。最后一行是首部Connection,通常将浏览器操作设置为Keep-Alive(当然也可以设置为其他值)。注意,在最后一个首部之后有一个空行。即使不存在请求主体,这个空行也是必需的
要发送GET请求的参数,则必须将这些额外的信息附在URL本身的后面。其格式类似于
URL ? name1=value1&name2=value2&..&nameN=valueN
该信息称之为查询字符串(query string),它将会复制在HTTP请求的请求行中,如下所示:
GET /books/?name=Professional%20Ajax HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Connection: Keep-Alive
HTTPPOST请求:
另一方面,POST请求在请求主体中为服务器提供了一些附加的信息。通常,当填写一个在线表单并提交它时,这些填入的数据将以POST请求的方式发送给服务器。以下就是一个典型的POST请求:
POST / HTTP/1.1
Host: www.baidu.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6)
Gecko/20050225 Firefox/1.0.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 40
Connection: Keep-Alive
name=Professional%20Ajax&publisher=Wiley
从上面可以发现, POST请求和GET请求之间有一些区别。
首先,请求行开始处的GET改为了POST,以表示不同的请求类型。你会发现首部Host和User-Agent仍然存在,在后面有两个新行。其中首部Content-Type说明了请求主体的内容是如何编码的。浏览器始终以application/ x-www-form- urlencoded的格式编码来传送数据,这是针对简单URL编码的MIME类型。首部Content-Length说明了请求主体的字节数。在首部Connection后是一个空行,再后面就是请求主体。与大多数浏览器的POST请求一样,这是以简单的“名称—值”对的形式给出的,其中name是Professional Ajax,publisher是Wiley。你可以以同样的格式来组织URL的查询字符串参数。
HTTP响应
如下所示,HTTP响应的格式与请求的格式十分类似:
<status-line>
<headers>
<blank line>
[<response-body>
正如你所见,
在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。以下就是一个HTTP响应的例子:
HTTP/1.1 200 OK
Date: Sat, 31 Dec 2005 23:59:59 GMT
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 122
<html>
<head>
<title>Wrox Homepage</title>
</head>
<body>
<!-- body goes here -->
</body>
</html>
在本例中,状态行给出的HTTP状态代码是200,以及消息OK。状态行始终包含的是状态码和相应的简短消息,以避免混乱。最常用的状态码有:
http://blog.sina.com.cn/s/blog_4ae187490100x9u7.html
◆200 (OK): 找到了该资源,并且一切正常。
◆304 (NOT MODIFIED): 该资源在上次请求之后没有任何修改。这通常用于浏览器的缓存机制。
◆401 (UNAUTHORIZED): 客户端无权访问该资源。这通常会使得浏览器要求用户输入用户名和密码,以登录到服务器。
◆403 (FORBIDDEN): 客户端未能获得授权。这通常是在401之后输入了不正确的用户名或密码。
◆404 (NOT FOUND): 在指定的位置不存在所申请的资源。
在状态行之后是一些首部。通常,服务器会返回一个名为Data的首部,用来说明响应生成的日期和时间(服务器通常还会返回一些关于其自身的信息,尽管并非是必需的)。接下来的两个首部大家应该熟悉,就是与POST请求中一样的Content-Type和Content-Length。在本例中,首部Content-Type指定了MIME类型HTML(text/html),其编码类型是ISO-8859-1(这是针对美国英语资源的编码标准)。响应主体所包含的就是所请求资源的HTML源文件(尽管还可能包含纯文本或其他资源类型的二进制数据)。浏览器将把这些数据显示给用户。