HTTP响应(HTTP Response)
  当Web服务器收到HTTP请求后,会根据请求的信息做某些处理(这些处理可能仅仅是静态的返回页,或是包含Asp.net,PHP,Jsp等语言进行处理后返回),相应的返回一个HTTP响应。HTTP响应在结构上很类似于HTTP请求,也是由三部分组成,分别为:
  1.状态行
  2.HTTP头
  3.返回内容
  首先来看状态行,一个典型的HTTP状态如下:
  HTTP/1.1 200 OK
  第一部分是HTTP版本,第二部分是响应状态码,第三部分是状态码的描述,因此也可以把第二和第三部分看成一个部分。
  对于HTTP版本没有什么好说的,而状态码值得说一下,网上对于每个具体的HTTP状态码所代表的含义都有解释,这里我说一下分类。
  信息类(100-199)
  响应成功(200-299)
  重定向类(300-399)
  客户端错误类(400-499)
  服务端错误类(500-599)
  HTTP响应中包含的头包括1.响应头(response header)2.普通头(general header)3.实体头(entity header)。
  第三部分HTTP响应内容是HTTP请求所请求的信息。这个信息可以是一个HTML,也可以是一个图片。比如我访问百度,HTTP Response如图5所示。


  图5.一个典型的HTTP响应

  图5中的响应是一个HTML,当然还可以是其它类型,比如图片,如图6所示。


  图6.HTTP响应内容是图片

  这里会有一个疑问,既然HTTP响应的内容不仅仅是HTML,还可以是其它类型,那么浏览器如何正确对接收到的信息进行处理?
  这是通过媒体类型确定的(Media Type),具体来说对应Content-Type这个HTTP头,比如图5中是text/html,图6是image/jpeg。
  媒体类型的格式为:大类/小类比如图5中的html是小类,而text是大类。
  IANA(The Internet Assigned Numbers Authority,互联网数字分配机构)定义了8个大类的媒体类型,分别是:
  application—(比如:application/vnd.ms-excel.)
  audio(比如:audio/mpeg.)
  image(比如:image/png.)
  message(比如,:message/http.)
  model(比如:model/vrml.)
  multipart(比如:multipart/form-data.)
  text(比如:text/html.)
  video(比如:video/quicktime.)
  HTTP头
  HTTP头仅仅是一个标签而已,比如我在Aspx中加入代码:
  Response.AddHeader(“测试头”,”测试值”);
  对应的我们可以在fiddler抓到的信息如图7所示。


  图7.HTTP头

  不难看出,HTTP头并不是严格要求的,仅仅是一个标签,如果浏览器可以解析会按照某些标准(比如浏览器自身标准,W3C的标准)去解释这个头,否则不识别的头会被浏览器无视。对服务器也是同理。假如你编写一个浏览器,你可以将上面的头解释成任何你想要的效果微笑
  下面我们说的HTTP头都是W3C标准的头,我不会对每个头的作用进行详细说明,关于HTTP头作用的文章在网上已经很多了,请自行Bing。HTTP头按照其不同的作用,可以分为四大类。
  通用头(General header)
  通用头即可以包含在HTTP请求中,也可以包含在HTTP响应中。通用头的作用是描述HTTP协议本身。比如描述HTTP是否持久连接的Connection头,HTTP发送日期的Date头,描述HTTP所在TCP连接时间的Keep-Alive头,用于缓存控制的Cache-Control头等。
  实体头(Entity header)
  实体头是那些描述HTTP信息的头。既可以出现在HTTP POST方法的请求中,也可以出现在HTTP响应中。比如图5和图6中的Content-Type和Content-length都是描述实体的类型和大小的头都属于实体头。其它还有用于描述实体的Content-Language,Content-MD5,Content-Encoding以及控制实体缓存的Expires和Last-Modifies头等。
  请求头(HTTP Request Header)
  请求头是那些由客户端发往服务端以便帮助服务端更好的满足客户端请求的头。请求头只能出现在HTTP请求中。比如告诉服务器只接收某种响应内容的Accept头,发送Cookies的Cookie头,显示请求主机域的HOST头,用于缓存的If-Match,If-Match-Since,If-None-Match头,用于只取HTTP响应信息中部分信息的Range头,用于附属HTML相关请求引用的Referer头等。
  响应头(HTTP Response Header)
  HTTP响应头是那些描述HTTP响应本身的头,这里面并不包含描述HTTP响应中第三部分也是HTTP信息的头(这部分由实体头负责)。比如说定时刷新的Refresh头,当遇到503错误时自动重试的Retry-After头,显示服务器信息的Server头,设置COOKIE的Set-Cookie头,告诉客户端可以部分请求的Accept-Ranges头等。
  状态保持
  还有一点值得注意的是,HTTP协议是无状态的,这意味着对于接收HTTP请求的服务器来说,并不知道每一次请求来自同一个客户端还是不同客户端,每一次请求对于服务器来说都是一样的。因此需要一些额外的手段来使得服务器在接收某个请求时知道这个请求来自于某个客户端。如图8所示。


  图8.服务器并不知道请求1和请求2来自同一个客户端

  通过Cookies保持状态
  为了解决这个问题,HTTP协议通过Cookies来保持状态,对于图8中的请求,如果使用Cookies进行状态控制,则变成了如图9所示。


  图9.通过Cookies,服务器可以清楚的知道请求2和请求1来自同一个客户端

  通过表单变量保持状态
  除了Cookies之外,还可以使用表单变量来保持状态,比如Asp.net通过一个叫ViewState的Input=“hidden”的框来保持状态,比如:
  <input type="hidden"name="__VIEWSTATE"id="__VIEWSTATE"value="/wEPDwUKMjA0OTM4MTAwNGRkXUfhlDv1Cs7/qhBlyZROCzlvf5U="/>
  这个原理和Cookies大同小异,只是每次请求和响应所附带的信息变成了表单变量。
  通过QueryString保持状态
  这个原理和上述两种状态保持方法原理是一样的,QueryString通过将信息保存在所请求地址的末尾来向服务器传送信息,通常和表单结合使用,一个典型的QueryString比如:
  www.xxx.com/xxx.aspx?var1=value&var2=value2
  总结
  本文从一个比较高的视角来看HTTP协议,对于HTTP协议中的细节并没有深挖,但对于HTTP大框架有了比较系统的介绍,更多关于HTTP的细节信息,请去Bing或参看相关书籍