原文:http://www.67bar.com/archives/1229html
HTTP由两部分组成:请求和响应。当你在Web浏览器中输入一个URL时,浏览器将根据你的要求建立并发送请求,该请求包含所输入的URL以及一些与浏览器自己相关的信息。当服务器收到这个请求时将返回一个响应,该响应包括与该请求相关的信息以及位于指定URL(若是有的话)的数据。直到浏览器解析该响应并显示出网页(或其余资源)为止。java
HTTP请求浏览器
HTTP请求的格式以下所示:缓存
<request-line> <headers> <blank line> [<request-body>]
在HTTP请求中,第一行必须是一个请求行(request line),用来讲明请求类型、要访问的资源以及使用的HTTP版本。服务器
紧接着是一个首部(header)小节,用来讲明服务器要使用的附加信息。并发
在首部以后是一个空行,再此以后能够添加任意的其余数据[称之为主体(body)]。app
在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(固然也能够设置为其余值)。注意,在最后一个首部以后有一个空行。即便不存在请求主体,这个空行也是必需的。url
要发送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
注意,为了将文本“Professional Ajax”做为URL的参数,须要编码处理其内容,将空格替换成%20,这称为URL编码(URL encoding),经常使用于HTTP的许多地方(JavaScript提供了内建的函数来处理URL编码和解码)。“名称—值”(name—value)对用 & 隔开。绝大部分的服务器端技术可以自动对请求主体进行解码,并为这些值的访问提供一些逻辑方式。固然,如何使用这些数据仍是由服务器决定的。
另外一方面,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的查询字符串参数。
下面是一些最多见的请求头:
Accept:浏览器可接受的MIME类型。 Accept – Charset:浏览器可接受的字符集。 Accept – Encoding:浏览器可以进行解码的数据编码方式,好比gzip。Servlet可以向支持gzip的浏览器返回经gzip编码的HTML页面。许多情形下这能够
减小5到10倍的下载时间。
Accept – Language:浏览器所但愿的语言种类,当服务器可以提供一种以上的语言版本时要用到。 Authorization:受权信息,一般出如今对服务器发送的WWW – Authenticate头的应答中。 Connection:表示是否须要持久链接。若是Servlet看到这里的值为“Keep – Alive”,或者看到请求使用的是HTTP 1.1(HTTP 1.1默认进行持久链接),它就能够利用持久链接的优势,当页面包含多个元素时(例如Applet,图片),显著地减小下载所须要的时间。要实现这一点,Servlet须要在应答中发送一个Content – Length头,最简单的实现方法是:先把内容写入ByteArrayOutputStream,而后在正式写出内容以前计算它的大小。 Content – Length:表示请求消息正文的长度。 Cookie:这是最重要的请求头信息之一,参见后面《Cookie处理》一章中的讨论。 From:请求发送者的email地址,由一些特殊的Web客户程序使用,浏览器不会用到它。 Host:初始URL中的主机和端口。 If – Modified – Since:只有当所请求的内容在指定的日期以后又通过修改才返回它,不然返回304“Not Modified”应答。 Pragma:指定“no – cache”值表示服务器必须返回一个刷新后的文档,即便它是代理服务器并且已经有了页面的本地拷贝。 Referer:包含一个URL,用户从该URL表明的页面出发访问当前请求的页面。 User – Agent:浏览器类型,若是Servlet返回的内容与浏览器类型有关则该值很是有用。 UA – Pixels,UA – Color,UA – OS,UA – CPU:由某些版本的IE浏览器所发送的非标准的请求头,表示屏幕大小、颜色深度、操做系统和CPU类型。
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。状态行始终包含的是状态码和相应的简短消息,以免混乱。最经常使用的状态码有:
◆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源文件(尽管还可能包含纯文本或其余资源类型的二进制数据)。浏览器将把这些数据显示给用户。
注意,这里并无指明针对该响应的请求类型,不过这对于服务器并不重要。客户端知道每种类型的请求将返回什么类型的数据,并决定如何使用这些数据。