2.3 HTTP报文格式
2.3.1 HTTP请求报文
HTTP报文有两种:请求报文和响应报文。
下面提供了一个典型的HTTP请求报文:
该报文是用普通的ASCII文本书写的,由5行组成,每行由一个回车和换行符结束。最后一行后再附加一个回车换行符。
一个请求报文能够具有更多的行或者至少为一行。
HTTP请求报文的第一行叫作请求行(request line),其后继的行叫作首部行(header line)。
请求行有3字段:方法字段、URL字段和HTTP版本字段。
方法字段可以取几种不同的值,包括GET、POST、HEAD、PUT和DELETE。
绝大部分的HTTP请求报文使用GET方法。
当浏览器请求一个对象时,使用GET方法,在URL字段带有请求对象的标识。
在本例中,该浏览器正在请求对象/somedir/page.html。
其版本字段是自解释的;在本例中,浏览器实现的是HTTP/1.1版本。
本例的首部行Host:www.someschool.edu指明了对象所在的主机。该首部行提供的信息是Web代理高速缓存所要求的。
通过包含Connection:close首部行,该浏览器告诉服务器不要麻烦地使用持续连接,它要求服务器在发送完被请求的对象后就关闭这条连接。
User-agent:首部行用来指明用户代理,即向服务器发送请求的浏览器的类型。这里浏览器类型是Mozilla/5.0,即Firefox浏览器。服务器可以有效地为不同类型的用户代理实际发送相同对象的不同版本。(每个版本都由相同的URL寻址。)
最后,Accept-language:首部行表示用户想得到该对象的法语版本(如果服务器中有这样的对象的话);否则,服务器应当发送它的默认版本。
一个请求报文的通用格式,如下图所示:
在首部请求行(和附加的回车和换行)后有一个“实体体”(enity body)。使用GET方法时实体体为空,而使用POST方法时才使用该实体体。
当用户提交表单时,HTTP客户常常使用POST方法,例如当用户向搜索引擎提供搜索关键词时。
使用POST报文时,用户仍可以向服务器请求一个Web页面,但Web页面的特定内容依赖于用户在表单字段中输入的内容。
如果方法字段的值为POST时,则实体体中包含的就是用户在表单字段中的输入值。
用表单生成的请求报文不是必须使用POST方法。相反,HTML表单经常使用GET方法,并在(表单字段中)所请求的URL中包括输入的数据。
例如,一个表单使用GET方法,它有两个字段,分别填写的是“monkeys和“bananas,这样,该URL结构为www.somesite.com/animalsearch?monkeys&bananas。
HEAD方法类似于GET方法。当服务器收到一个使用HEAD方法的请求时,将会用个HTTP报文进行响应,但是并不返回请求对象。应用程序开发者常用HEAD方法进行调试跟踪。
PUT方法常与Web发行工具联合使用,它允许用户上传对象到指定的Web服务器上指定的路径(目录)。PUT方法也被那些需要向Web服务器上传对象的应用程序使用。
DELETE方法允许用户或者应用程序删除Web服务器上的对象。
2.3.2 HTTP响应报文
一条典型的HTTP响应报文,如下图所示:
该响应报文可以是对刚刚讨论的例子中请求报文的响应。
响应报文有三个部分:
一个初始状态行(status line),6个首部行(header line),然后是实体体(entity body。实体体部分是报文的主要部分, 即它包含了所请求的对象本身(表示为data data data data data…)。
状态行有3个字段:协议版本字段、状态码和相应状态信息。
在这个例子中,状态行指示服务器正在使用HTTP/1.1,并且一切正常(即服务器已经找到并正在发送所请求的对象)。
服务器用Connection:close首部行告诉客户,发送完报文后将关闭该TCP连接。
Date:首部行指示服务器产生并发送该响应报文的日期和时间。
值得一提的是,这个时间是服务器从它的文件系统中检索到该对象,将该对象插入响应报文,并发送该响应报文的时间。
Server:该报文是由一台Apache Web服务器产生的,它类似于HTTP请求报文中的User-agent:首部行。
Last-Modified:首部行指示了对象创建或者最后修改的日期和时间。Last-Modified:首部行对既可能在本地客户也可能在网络缓存服务器上的对象缓存来说非常重要。
Content Length:首部行指示了被发送对象中的字节数。
Content-Type:首部行指示了实体体中的对象是HTML文本。
响应报文的通用格式,如下图所示:
该通用格式与前面例子中的响应报文相匹配。
一些常见的状态码和相关的短语包括:
- 200 OK:请求成功,信息在返回的响应报文中。
- 301 Moved Permanently:请求的对象已经被永久转移了,新的URL定义在响应报文的Location:首部行中。客户软件将自动获取新的URL。
- 400 Bad Request:一个通用差错代码,指示该请求不能被服务器理解。
- 404 NotFound:被请求的文档不在服务器上。
- 505 HTTP Version Not Supported:服务器不支持请求报文使用的HTTP协议版本。
2.4 用户与服务器的交互:cookie
HTTP服务器是无状态的,然而一个Web站点通常希望能够识别用户。为此,HTTP使用了cookie,它允许站点对用户进行跟踪。
cookie技术有4个组件:
① 在HTTP响应报文中的一个cookie首部行;
② 在HTTP请求报文中的一个cookie首部行;
③ 在用户端系统中保留有一个cookie文件,并由用户的浏览器进行管理;
④ 位于Web站点的一个后端数据库。
通过一个典型的例子来看cookie的工作过程:
假设Susan总是从家中PC使用Internet Explorer上网,她首次与Amazon.com联系。
假定过去她已经访问过eBay站点。
当请求报文到达该Amazon Web服务器时,该Web站点将产生一个唯一识别码,并以此作为索引在它的后端数据库中产生一个表项。
接下来Amazon Web服务器用一个包含Set-cookie:首部的HTTP响应报文对Susan的浏览器进行响应。
其中Set-cookie:首部含有该识别码。
例如,该首部行可能是
Set-cookie: 1678
当Susan的浏览器收到了该HTTP响应报文时,它会看到该Set-cookie:首部。
该浏览器在它管理的特定cookie文件中添加一行,该行包含服务器的主机名和在Set-cookie:中的识别码。
值得注意的是,该cookie文件已经有了用于eBay的表项,因为Susan过去访问过该站点。
当Susan继续浏览Amazon网站时,每请求一个Web页面,其浏览器就会查询该cookie文件并抽取她对这个网站的识别码,并放到HTTP请求报文中包括识别码的cookie首部行中。
特别是,发往该Amazon服务器的每个HTTP请求报文都包括以下首部行:
Cookie: 1678
在这种方式下,Amazon服务器可以跟踪Susan在Amazon站点的活动。
尽管AmazonWeb站点不必知道Susan的名字,但它确切地知道用户1678按照什么顺序、在什么时间、访问了哪些页面!
Amazon使用cookie来提供它的购物车服务,即Amazon能够维护Susan希望购买的物品列表,这样在Susan结束会话时可以一起为它们付费。
如果Susan再次访问Amazon站点,比如说一个星期后,她的浏览器会在其请求报文中继续放入首部行cookie: 1678。
Amazon将根据Susan过去在Amazon访问的网页向她推荐产品。
如果Susan也在Amazon注册过,即提供了她的全名、电子邮件地址、邮政地址和信用卡账号,则Amazon能在其数据库中包括这些信息, 将Susan的名字与识别码相关联(以及她在过去访问过的本站点的所有页面)。
这就解释了Amazon和其他一些电子商务网站实现“点击购物”(one-click shopping)的道理,即当Susan在后继的访问中选择购买某个物品时,她不必重新输入姓名、信用卡账号或者地址等信息了。
cookie可以用于标识一个用户。用户首次访问一个站点时,可能需要提供一个用户标识(可能是名字)。
在后继会话中,浏览器向服务器传递一个cookie首部,从而向该服务器标识了用户。
因此,cookie可以在无状态的HTTP之上建立一个用户会话层。
参考
《计算机网络——自顶向下方法》 —— 2 应用层