HTTP协议简介
HTTP协议,全名HyperText Transfer Protocol,是目前互联网上应用最广泛的协议之一。通过HTTP协议,Web服务器和浏览器之间就可以在互联网上发送和接受数据了。HTTP协议简单来讲就是一个request和response的协议,客户端向服务器发送一个资源请求,服务端返回客户端请求的数据。
第一版的HTTP协议是HTTP/0.9, 然后很快就被HTTP/1.0版代替了,最新版的HTTP协议是HTTP/1.1版本的,RFC的全文可下载此PDF查看http://www.w3.org/Protocols/HTTP/1.1/rfc2616.pdf
HTTP协议中,总是由客户端先发起一个HTTP请求然后建立起一个连接,服务端没有义务去主动和客户端建立连接,也不会发起一个callback连接。浏览器与服务端的任何一方都可以随时中断连接。例如,当你在浏览器中下载一个文件时,你可以随时点击取消或停止按钮来中止下载一个文件。
HTTP Requests
一个HTTP Request请求由在三个部门组成:
请求的方法—URI—HTTP协议与版本
请求头
请求体
一个简单的HTTP请求如:
POST /examples/default.jsp HTTP/1.1
Accept: text/plain; text/html Accept-Language: en-gb Connection: Keep-Alive
Host: localhost
User-Agent: Mozilla/4.0 (compatible; MSIE 4.01; Windows 98) Content-Length: 33
Content-Type: application/x-www-form-urlencoded Accept-Encoding: gzip, deflate
lastName=Franks&firstName=Michael
- 方法 URI HTTP协议的版本位于请求的第一行,POST是请求的方法,/examples/default.jsp是URI部分,HTTP/1.1是协议与版本。
HTTP标准中,请求的方法支持7种:GET,POST,HEAD,OPTIONS,PUT,DELETE和TRACE,其中GET和POST是互联网上用的最多的请求方法。 - URI用于定位一个资源,一个URI常常被解析为相对路径于服务器的根节点目录。URL请求其实是URI的一种,详情可以参考:http://www.ietf.org/rfc/rfc2396.txt
- 第二部分是请求的Header部分,它通常包括含了请求的客户端的环境信息和请求体的相关信息等。例如,它包括浏览器使用的语言,请求体的长度等等,每个Header通过一个回车(CRLF)来分隔。
- 在请求体与请求内容之前,有一个空行(CRLF),这个大家得非常注意,因为很多人没有注意到。这个空行告诉HTTP服务器请求体开始了,在一些书籍上,这个CRLF空行也被称着HTTP请求中的第四个元素。
- 最后一个部分是请求体,例子中的是
lastName=Franks&firstName=Michael
HTTP Responses
类似于HTTP Request,Http Response也是由三个部门组成:
协议—状态码—描述
应答头
应答体
HTTP/1.1 200 OK
Server: Microsoft-IIS/4.0
Date: Mon, 5 Jan 2004 13:13:33 GMT Content-Type: text/html
Last-Modified: Mon, 5 Jan 2004 13:13:12 GMT Content-Length: 112
<html>
<head>
<title>HTTP Response Example</title> </head>
<body>
Welcome to Brainy Software
</body>
</html>
第一行和HTTP请求类似,先是HTTP协议和版本,200是请求成功返回了,OK代表200的一个简单描述,注意同样应答头与应答体之前有一个空行(CRLF)。
HTTP 1.1协议
1997年1月,HTTP/1.1 版本发布,只比 1.0 版本晚了半年。它进一步完善了 HTTP 协议,一直用到了20年后的今天,直到现在还是最流行的版本。
持久连接
1.1 版最大的变化就是引入的持久连接(persistent connection), 即TCP连接默认不关闭,可以被多个请求复用,不用声明Connection: keep-alive。
管道机制
1.1 版还引入了管道机制(pipelining),即在同一个TCP连接里面,客户端可以同时发送多个请求。这样就进一步改进了HTTP协议的效率。
举例来说,客户端需要请求两个资源。以前的做法是,在同一个TCP连接里面,先发送A请求,然后等待服务器做出回应,收到后再发出B请求。管道机制则是允许浏览器同时发出A请求和B请求,但是服务器还是按照顺序,先回应A请求,完成后再回应B请求。
Content-Length 字段
一个TCP连接现在可以传送多个回应,势必就要有一种机制,区分数据包是属于哪一个回应的。这就是Content-length字段的作用,声明本次回应的数据长度。
Content-Length: 3495
上面代码告诉浏览器,本次回应的长度是3495个字节,后面的字节就属于下一个回应了。
在1.0版中,Content-Length字段不是必需的,因为浏览器发现服务器关闭了TCP连接,就表明收到的数据包已经全了。
分块传输编码
使用Content-Length
字段的前提条件是,服务器发送回应之前,必须知道回应的数据长度。
对于一些很耗时的动态操作来说,这意味着,服务器要等到所有操作完成,才能发送数据,显然这样的效率不高。更好的处理方法是,产生一块数据,就发送一块,采用"流模式"(stream)取代"缓存模式"(buffer)。
因此,1.1版规定可以不使用Content-Length
字段,而使用"分块传输编码"(chunked transfer encoding)。只要请求或回应的头信息有Transfer-Encoding
字段,就表明回应将由数量未定的数据块组成。
Transfer-Encoding: chunked
每个非空的数据块之前,会有一个16进制的数值,表示这个块的长度。最后是一个大小为0的块,就表示本次回应的数据发送完了。下面是一个例子。
HTTP/1.1 200 OK
Content-Type: text/plain
Transfer-Encoding: chunked
25
This is the data in the first chunk
1C
and this is the second one
3
con
8
sequence
0
其他功能
1.1版还新增了许多动词方法:PUT、PATCH、HEAD、 OPTIONS、DELETE。
另外,客户端请求的头信息新增了Host字段,用来指定服务器的域名。
Host: www.example.com
有了Host字段,就可以将请求发往同一台服务器上的不同网站,为虚拟主机的兴起打下了基础。
网友评论