以前写过一篇HTML报文,可是感受写完以后仍是不懂,最近终于有时间开始看《HTTP权威指南》,看完以后以为仍是比以前的理解更加深刻了,提取HTTP报文出来作个记录。html
HTTP报文分为请求报文(request message)与响应报文(response message)。api
1、报文的组成部分浏览器
一个HTTP报文由3部分组成,分别是:缓存
(1)、起始行(start line)安全
(2)、首部(header)服务器
(3)、主体(body)cookie
示例:并发
HTTP/1.0 200 OK //起始行 Content-type:text/plain //首部 Content-length:19 //首部 Hi I'm a message! 主体
1.1 请求报文与响应报文的格式app
请求报文的格式:dom
<method> <request-UTL> <version> <headers> <entity-body>
响应报文的格式:
<version> <status><reason-phrase> <header> <entity-body>
留意到请求报文与响应报文只是起始行不一样。
下面是对格式中各部分的简要描述
一、方法(method) GET
客户端但愿服务器对资源执行的动做。是一个单独的词,好比GET、HEAD或POST。
二、请求的URL(request-URL) www.baidu.com
命名了全部请求资源,或者URL路径组件的完整URL。若是直接与服务器进行对话,只要URL的路径组件是资源的绝对路径,一般就不会有什么问题--服务器能够假定 本身是URL的主机/端口。
三、版本(version) HTTP/1.1
报文所使用的HTTP版本,其格式以下:
HTTP/<major>.<minor>
其中主要版本号(major)和次要版本号(minor)都是整数。
四、状态码(status)
这三个数字描述了请求过程当中所发生的状况。每一个状态码的第一位数字都用于描述状态的通常类别("成功"、"出错"等)。 200
五、缘由短语(reason-phrase)
数字状态码的可读版本,包含行终止序列以前的全部文本。缘由短语只是给人类看的,它不能说明什么。客户端依然采用状态码来判断请求/响应是否成功!
例如:HTTP/1.0 200 NOT OK 客户端依然会当请求已成功处理。由于状态码是200。而缘由短语只是说明而已,这对于自定义扩展状态码仍是比较有用的。
六、首部(header)
能够有0个或多个首部,每一个首部都包含一个名字,后面跟着一个冒号(:),而后是一个可选的空格,接着是一个值,最后是一个CRLF。首部是由一个空行(CRLF)结束 的,表示了首部列表的结束和实体主体的开始。
七、实体的主体部分(entity-body)
实体的主体部分包含一个由任意数据组成的数据块。并非全部的报文都包含实体的主体部分。如GET请求就不包含实体。
2、起始行
一、请求行
请求报文的起始行,或称为请求行。包含了一个方法和一个请求的URL。这个方法描述了服务器应该执行的操做,请求URL描述了要对哪一个资源执行这个方法。请求行中还包含HTTP的版本,用来告知服务器,客户端使用的是哪一种HTTP版本。如:
GET /info/123.html HTTP/1.1 //方法为GET URL为 /info/123.html HTTP协议版本为1.1
1.1方法
下面给出请求报文中方法的列表
方法 描述 是否包含主体
GET 从服务器获取一份文档 否
HEAD 只从服务器获取文档的首部 否
POST 向服务器发送须要处理的数据 是
PUT 将请求的主体部分存储在服务器上 是
TRACE 对可能通过代理服务器传送到服务器上去的报文进行跟踪 否
OPTIONS 决定能够在服务器上执行哪些方法 否
DELETE 从服务器上删除一份文档 否
1.2 request-URL
跳过,不说你也知道。
1.3 版本(version)
版本号会以HTTP/x.y 的形式出如今请求和响应报文的起始行中。为HTTP应用程序提供了一种将本身遵循的协议版本告知对方的方式。版本号说明了应用程序支持的最高HTTP版本。注意,版本号不会被当作小数来处理。所以在比较HTTP版本时,每一个数字都必须单独作比较,以便肯定哪一个版本更高。如HTTP/2.22就比HTTP/2.3要高,由于22比3大。
1.4 状态码(status-code)
方法是用来告诉服务器作什么事情,而状态码则用来告诉客户端发生了什么事情。
下面给出状态码的经常使用分类
总体范围 已定义范围 分类
100-199 100-101 信息提示
200-299 200-206 成功
300-399 300-305 重定向
400-499 400-415 客户端错误
500-599 500-505 服务器错误
下面再说几个最多见的状态码。200-OK-成功,请求的全部数据都在响应主体中。401-Unauthorized(未受权)-须要输入用户名和密码。404-Not Found(未找到)-服务器没法找到所请求URL对应的资源。
1.5缘由短语
缘由短语是响应起始行中的最后一个组件。它为状态码提供了文本形式的解释。好比在HTTP/1.0 200 OK 中,OK就是缘由短语。缘由短语和状态码是成对出现的。缘由短语是状态码的可读版本,应用程序开发者将其传送给用户,用以说明请求期间发生了什么状况。客户端判断服务器状态依据的是状态码,与缘由短语没有半毛钱关系。
3、首部
HTTP首部字段向请求和响应报文中添加了一些附加信息。本质上来讲,它们只是一些名/值对的列表。好比下面的首部行会向Content-Length首部字段赋值19:
Content-length:19
一、首部分类
HTTP规范定义了几种首部字段。应用程序也能够随意发明本身所用的首部。HTTP首部能够分为如下几类。
(1)、通用首部:既能够出如今请求报文中,也能够出如今响应报文中。
这些是客户端和服务器均可以使用的通用首部。能够在客户端、服务器和其余应用程序之间提供一些很是有用的通用功能。他们像和事佬同样,,不论报文是何种 类型,都为其提供一些有用的信息。例如无论是构建请求报文仍是响应报文,建立报文的日期时间都是同一个意思,所以提供这类信息的首部对这两种类型的报文来讲 都是通用的。下面用表格的形式给出通用的信息性首部。
通用的信息性首部:
首部 描述
Connection 容许客户端和服务器指定与请求/响应链接有关的选项
Date 提供日期和时间标志,说明报文是什么时间建立的
MIME-Version 给出了发送端使用的MIME版本
Trailer 若是报文采用了分块传输编码(chunked transfer encoding)方式,就能够用这个首部列出位于报文拖鞋 (trailer)部分的首部集合。
Transfer-Encoding 告知接收端为了保证报文的可靠传输,对报文采用了什么编码方式。
Update 给出了发送端可能想要"升级"使用的新版本或协议
Via 显示了报文通过的中间节点(代理、网关)
通用缓存首部:
首部 描述
Cache-Control 用于随报文传送缓存指示
Pragma 另外一种随报文传送指示的方式,但并不专用于缓存
(2)、请求首部:提供更多有关请求的信息。
请求首部是在请求报文中有意义的首部。用于说明是谁或什么在发送请求,请求源自何处,或者客户端的喜爱及能力。服务器能够根据请求首部给出的客户端的信 息,试着为客户端提供更好的响应。
请求的信息性首部:
首部 描述
Client-IP 提供了运行客户端的机器的IP地址
From 提供了客户端用户的E-mail地址
Host 给出了接收请求的服务器的主机名和端口号
Referer 提供了包含当前请求URI的文档的URL
UA-Color 提供了与客户端显示器的显示颜色有关的信息
UA-CPU 给出了客户端CPU的类型或制造商
US-Disp 提供了与客户端显示器(屏幕)能力有关的信息
US-OS 给出了客户端显示器的像素信息
UA-Pixels 提供了客户端显示器的像素信息
User-Agent 将发起请求的应用程序名称告知服务器(User-Agent)用户代理,其实不就是浏览器吗
Accept首部为客户端提供了一种将其喜爱和能力告知服务器的方式,包括他们想要什么,可使用什么,以及最重要的,他们不想要什么。这样服务器就能够根据这些额外信息,对要发送的内容作出更明智的决定。Accept首部会使链接的两端都受益。客户端会获得他们想要的内容,服务器则不会浪费其时间和带宽来发送客户端没法使用的东西。
Accept首部:
首部 描述
Accept 告诉服务器可以发送哪些媒体类型
Accept-Charset 告诉服务器可以发送哪些字符集
Accept-Encoding 告诉服务器可以发送哪些编码方式
Accept-Language 告诉服务器可以发送哪些语言
TE 告诉服务器可使用哪些扩展传输编码
条件请求首部:
有时客户端但愿为请求加上某些限制。好比客户端已经有了一份副本,就但愿只在服务器上的文档与客户端拥有的副本有所区别时,才请求服务器传输文档。经过条件请求首部,客户端就能够加上这种限制,要求服务器在对请求进行相应以前,确保某个请求为真。
条件请求首部:
首部 描述
Expect 容许客户端列出某请求所要求的服务器行为
If-Match 若是实体标记与文档当前的实体标记相匹配,就或者这份文档
If-Modified-Since 除非在某个指定的日期以后资源被修改过,不然就限制这个请求
If-Range 容许对文档的某个范围进行条件请求
If-Unmodified-Since 除非在某个指定的日期以后资源没有被修改过,不然就限制这个请求
Range 若是服务器支持范围请求,就请求资源的指定范围
安全请求首部:
HTTP自己就支持一种简单的机制,能够对请求进行质询/响应认证。这种机制要求客户端在获取特定的资源以前,先对自身进行认证,这样就可使事务稍微安全一些。
安全请求首部:
首部 描述
Authorization 包含了客户端提供给服务器,以便对其自身进行认证的数据
Cookie 客户端用它想服务器传送一个令牌-他并非真正的安全首部,但倒是隐含了安全功能
Cookie2 用来讲明请求端支持的cookie版本
代理请求首部:
随着因特网上代理的广泛应用,人们定义了几个首部来协助其更好地工做。
代理请求首部:
首部 描述
Max-Forword 在通往源端服务器的路径上,将请求转发给其余代理或网关的最大次数-与TRACE方法一同使用
Proxy-Authorization 与Authorization首部相同,但这个首部是在与代理进行认证时使用的
Proxy-Connection 与Connection首部相同,但这个首部是在于代理创建链接时使用的
(3)、响应首部:提供更多有关响应的信息。
响应报文由本身的响应首部集。响应首部为客户端提供了一些额外的信息,好比谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令。这些首部有助于客 户端处理响应,并在未来发起更好的请求。
响应的信息性首部:
首部 描述
Age (从最初建立开始)响应持续时间
Public 服务器为其资源支持的请求方法列表
Retry-After 若是资源不可用的话,再第二天期或时间重试
Server 服务器应用程序软件的名称和版本
Title 对HTML文档来讲,就是HTML文档的源端给出的标题
Warning 比缘由短语中更详细的一些警告报文
协商首部:若是资源有多种表示方法-好比,若是服务器上有某文档的法语和德语译稿,HTTP/1.1能够为服务器和客户端提供对资源进行协商的能力。
协商首部:
首部 描述
Accept-Ranges 对此资源来讲,服务器可接受的范围类型
Vary 服务器查看的其余首部的列表,可能会使响应发生变化;也就是说,这是一个首部列表,服务器会根据这些首部的内容挑选出最合适的资源版本 发送给客户端。
安全响应首部:
咱们已经看到过安全请求首部了,本质上这里说的就是HTTP的质询/响应认证机制的响应侧。
安全响应首部:
首部 描述
Proxy-Authenticate 来自代理的对客户端的质询列表
Set-Cookie 不是真正的安全首部,但隐含有安全功能;能够在客户端设置一个令牌,以便服务器对客户端进行标识。
Set-Cookie2 与Set-Cookie相似。
WWW-Authenticate 来自服务器的对客户端的质询列表
d、实体首部:描述主体的长度和内容,或者资源自身。
有不少首部能够用来描述HTTP报文的负荷。因为请求和响应文本中均可能包含实体部分,因此在这两种类型的报文中均可能出现这些首部。实体首部提供了有关实体及 其内容的大量信息,从有关对象类型的信息,到可以对资源使用的各类有效的请求方法。总之,实体首部能够告知报文的接收者它在对什么进行处理。
实体信息性首部:
首部 描述
Allow 列出了能够对此实体执行的请求方法
Location 告知客户端实体实际上位于何处;用于将接收端定向到资源的位置上去
内容首部:
内容首部提供了与实体内容有关的特定信息,说明了其类型、尺寸以及处理它所需的其余有用信息。好比,Web浏览器能够经过查看返回的内容类型,得知如何显示对象。
内容首部:
首部 描述
Content-Base 解析主体中的相对URL时使用的基础URL
Content-Encoding 对主体执行的任意编码方式
Content-Language 理解主体时最适宜使用的天然语言
Content-Length 主体的长度或尺寸
Content-Location 资源实际所处的位置
Content-MD5 主体的MD5校验
Content-Range 在整个资源中此实体表示的字节范围
Content-Type 这个主体的对象模型
实体缓存首部:
通用的缓存首部说明了如何或何时进行缓存。实体的缓存首部提供了与被缓存实体有关的信息,好比验证已缓存的资源副本是否仍然有效所需的信息,以及更好地估计已缓存资源合适失效所需的线索。
实体缓存首部
首部 描述
ETag 与此实体有关的实体标记
Expires 实体不在有效,要从原始的源端再次获取此实体的日期和时间
Last-Modified 这个实体最后一次被修改的日期和时间
e、扩展首部:规范中没有定义的新首部。
每一个HTTP首部都有一种简单的语法:名字后面跟着冒号(:),而后跟上可选的空格,再跟上字段值。最后是一个回车换行。
二、首部延续行
将长的首部行分为多行能够提升可读性,多出来的每行前面至少要有一个空格或制表符(tab)。
HTTP/1.0 200 OK
Content-Type: image/gif
Content-Length: 8572
Server: Test Server
Version 1.0
在上面的例子中,响应报文里包含了一个Server首部,其值被划分红了多个延续行,该首部的完整值为Test Server Version 1.0。
4、实体部分
HTTP的第三部分是可选的实体主体部分,实体的主体是HTTP报文的负荷。就是HTTP要传输的内容。
HTTP报文能够承载不少类型的数字数据,图片、视频、HTML文档、软件应用程序、信用卡事务、电子邮件等。
下面来实战下,咱们用浏览器打开百度首页,将HTTP报文实战解析下:
打开百度的请求报文:
GET / HTTP/1.1 //请求方法为GET,HTTP协议为1.1 Host: www.baidu.com //URL为www.baidu.com User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:19.0) Gecko/20100101 Firefox/19.0 //用户代理,也就是浏览器了,显示了浏览器的详细信息 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 //服务器可以发送的文件类型text/html的意思是HTML文本文档类型,后面那些查文档去 Accept-Language: zh-cn,zh;q=0.8,en-us;q=0.5,en;q=0.3 //服务器可以发送的语言 zh-cn为中文,后面那些查文档去 Accept-Encoding: gzip, deflate //服务器可以发送的编码格式为gzip,编码格式不符合浏览器会解释不了 Cookie: BAIDUID=AF6C346B14E94898933E5F858C63F889:FG=1; BDREFER=%7Burl%3A%22http%3A//news.baidu.com/%22%2Cword%3A%22%22%7D; H_PS_PSSID=2097_1464_2133_1944_1788 //cookie,服务器存储在客户端的信息,每次请求都会将服务器保存在客户端的cookie一并发送上服务器。 Connection: keep-alive //链接,keep-alive保持状态 Cache-Control: max-age=0 //随报文传送缓存指示 cache-control max-age>0 时 直接从游览器缓存中 提取 max-age<=0 时 向server 发送http 请求确认 ,该资源是否有修改 有的话 返回200 ,无的话 返回304.
打开百度的响应报文:
HTTP/1.1 200 OK //HTTP版本 1.1 状态码200 缘由短语OK Date: Tue, 02 Apr 2013 04:27:50 GMT //响应的时间日期 Server: BWS/1.0 //服务器应用程序软件的名称和版本 BWS/1.0 Content-Length: 4271 //响应的主体内容的长度为4271个字节 Content-Type: text/html;charset=utf-8 //响应类型为HTML文本,编码类型为utf-8 Cache-Control: private //缓存指示 Expires: Tue, 02 Apr 2013 04:27:50 GMT //实体不在有效,要从原始的源端再次获取此实体的日期和时间 Content-Encoding: gzip //对主体执行的编码方式为gzip Set-Cookie: H_PS_PSSID=2097_1464_2133_1944_1788; path=/; domain=.baidu.com //设置cookie,path,domain都是cookie的信息(做用范围等等) Connection: Keep-Alive //状态为保持链接
响应就牛B了,就是页面的源代码:
<!DOCTYPE html><!--STATUS OK--> <html><head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>百度一下,你就知道</title> <style >html,body{height:100%}html{overflow-y:auto}#wrapper{position:relative;_position:;min-height:100%}#content{padding-bottom:100px;text-align:center}#ftCon{height:100px;position:absolute;bottom:44px;text-align:center;width:100%;margin:0 auto;z-index:0;overflow:hidden}#ftConw{width:720px;margin:0 auto}body{font:12px arial;text-align:;background:#fff}body,p,form,ul,li{margin:0;padding:0;list-style:none}body,form,#fm{position:relative}td{text-align:left}img{border:0}a{color:#00c}a:active{color:#f60}#u{color:#999;padding:4px 10px 5px 0;text-align:right}#u a{margin:0 5px}#u .reg{margin:0}#m{width:720px;margin:0 auto}#nv a,#nv b,.btn,#lk{font-size:14px}#fm{padding-left:110px;text-align:left;z-index:1}...
因为内容比较多,因此省略后面部分
下面来看下一个须要提交表单的请求报文:打开百度的登陆窗口,填写完信息后提交是的请求报文POST信息为:
callback parent.bdPass.api.login._postCallback charset utf-8 codestring index 0 isPhone false loginType 1 mem_pass on password 123 ppui_logintime 13905 safeflg 0 staticpage http://www.baidu.com/cache/user/html/jump.html token d0de247f344d33dbb9692491dc5574cd tpl mn u username 123@qwe.com verifycode
能够看到在表单提交的请求帐号密码都在请求报文的实体里面传送上服务器了。