HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。HTTP有两类报文:请求报文和响应报文。
1 HTTP请求报文
一个HTTP请求报文由请求行
(request line)、请求头部
(header)、空行
和请求数据
4个部分组成,下图给出了请求报文的一般格式。
or
<request-line>
<headers>
<blank line>
[<request-body>
1.1 请求行
请求行由请求方法字段
、URL字段
和HTTP协议版本
字段3个字段组成,它们用空格分隔。例如,GET /index.html HTTP/1.1。
HTTP协议的请求方法有 GET、POST、HEAD、PUT、DELETE、OPTIONS、TRACE、CONNECT
。
而常见的有如下几种:
1)、GET
最常见的一种请求方式,当客户端要从服务器中读取文档时
,当点击网页上的链接
或者通过在浏览器的地址栏输入网址来浏览网页
的,使用的都是GET方式
。GET方法要求服务器将URL定位的资源放在响应报文的数据部分
,回送给客户端。使用GET方法时,请求参数和对应的值附加在URL后面,利用一个问号(“?”)代表URL的结尾与请求参数的开始,传递参数长度受限制。例如,/index.jsp?id=100&op=bind,这样通过GET方式传递的数据直接表示在地址中,所以我们可以把请求结果以链接的形式发送给好友。以用google搜索domety为例,Request格式如下:
GET /search?hl=zh-CN&source=hp&q=domety&aq=f&oq= HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, application/x-silverlight, application/x-shockwave-flash, */*
Referer: <a href="http://www.google.cn/">http://www.google.cn/</a>
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)
Host: <a href="http://www.google.cn">www.google.cn</a>
Connection: Keep-Alive
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
FxlRugatx63JLv7CWMD6UB_O_r
可以看到,GET方式的请求一般不包含”请求内容”部分,请求数据以地址的形式表现在请求行。地址链接如下:
<a href="http://www.google.cn/search?hl=zh-CN&source=hp&q=domety&aq=f&oq=">http://www.google.cn/search?hl=zh-CN&source=hp
&q=domety&aq=f&oq=</a>
地址中”?”之后的部分就是通过GET发送的请求数据,我们可以在地址栏中清楚的看到,各个数据之间用”&”符号隔开。显然,这种方式不适合传送私密数据。另外,由于不同的浏览器对地址的字符限制也有所不同,一般最多只能识别1024个字符,所以如果需要传送大量数据的时候,也不适合使用GET方式。
2)、POST
对于上面提到的不适合使用GET方式的情况,可以考虑使用POST方式,因为使用POST方法可以允许客户端给服务器提供信息较多。POST方法将请求参数封装在HTTP请求数据中,以名称/值的形式出现,可以传输大量数据,这样POST方式对传送的数据大小没有限制,而且也不会显示在URL中。还以上面的搜索domety为例,如果使用POST方式的话,格式如下:
POST /search HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/vnd.ms-excel, application/vnd.ms-powerpoint,
application/msword, application/x-silverlight, application/x-shockwave-flash, */*
Referer: <a href="http://www.google.cn/">http://www.google.cn/</a>
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727; TheWorld)
Host: <a href="http://www.google.cn">www.google.cn</a>
Connection: Keep-Alive
Cookie: PREF=ID=80a06da87be9ae3c:U=f7167333e2c3b714:NW=1:TM=1261551909:LM=1261551917:S=ybYcq2wpfefs4V9g;
NID=31=ojj8d-IygaEtSxLgaJmqSjVhCspkviJrB6omjamNrSm8lZhKy_yMfO2M4QMRKcH1g0iQv9u-2hfBW7bUFwVh7pGaRUb0RnHcJU37y-
FxlRugatx63JLv7CWMD6UB_O_r
hl=zh-CN&source=hp&q=domety
可以看到,POST方式请求行中不包含数据字符串,这些数据保存在”请求内容”部分,各数据之间也是使用**”&”符号隔开**。POST方式大多用于页面的表单中。因为POST也能完成GET的功能,因此多数人在设计表单的时候一律都使用POST方式,其实这是一个误区。GET方式也有自己的特点和优势,我们应该根据不同的情况来选择是使用GET还是使用POST。
3)、HEAD
HEAD就像GET,只不过服务端接受到HEAD请求后只返回响应头,而不会发送响应内容。当我们只需要查看某个页面的状态
的时候,使用HEAD是非常高效的
,因为在传输的过程中省去了页面内容
。不包含主体
4)、TRACE
主要用于验证请求 是否如愿穿过了请求/响应链
,不包含主体
5)、OPTIONS方法
决定可以在服务器上执行那些方法
,不包含主体
6)、DELETE方法
该方法就是请服务器 删除 请求URL所指定的资源
,但是客户端应用程序无法保证删除操作一定会被执行
,因为HTTP规范 允许 服务器 在不通知客户端的情况下 撤销请求
,不包含主体
7)、PUT方法
该方法的语义就是让服务器 用请求的主体部分 来创建一个 由所请求的URL命名的新文档
,如果那个URL已经存在的话
,就用这个主体来替代它
。包含主体
1.2 请求头部
请求头部
由关键字/值对
组成,每行一对,关键字和值用英文冒号“:”分隔
。请求头部通知服务器有关于客户端请求的信息
,典型的请求头有:
User-Agent
:产生请求的浏览器类型
。Accept
:客户端可识别的内容类型列表
。Host
:请求的主机名
,允许多个域名同处一个IP地址
,即虚拟主机
。
1.3 空行
最后一个请求头
之后是一个空行
,发送回车符和换行符,通知服务器以下不再有请求头
。
1.4 请求数据
请求数据不在GET方法中使用
,而是在POST方法中使用
。POST方法适用于需要客户填写表单的场合。与 请求数据相关 的 最常使用的 请求头是Content-Type(这个主体的对象类型)和Content-Length(主体的长度)
。
2 HTTP响应报文
HTTP响应也由三个部分组成,分别是:状态行
、消息报头
、响应正文
。
如下所示,HTTP响应的格式与请求的格式十分类似:
<status-line>
<headers>
<blank line>
[<response-body>]
正如你所见,在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行
(status line)通过提供
一个状态码
来说明所请求的资源情况
。
2.1 状态行格式如下:
HTTP-Version Status-Code Reason-Phrase CRLF
其中,HTTP-Version
表示服务器HTTP协议的版本
;Status-Code
表示服务器发回的响应状态代码
;Reason-Phrase
表示状态代码的文本描述
。状态代码
由三位数字组成,第一个数字
定义了响应的类别
,且有五种可能取值。
- 1xx:指示信息–表示
请求已接收,继续处理
。 - 2xx:成功–表示
请求已被成功接收、理解、接受
。 - 3xx:重定向–要完成
请求必须进行更进一步的操作
。 - 4xx:客户端错误–
请求有语法错误
或请求无法实现
。 - 5xx:服务器端错误–
服务器未能实现合法的请求
。
常见状态代码、状态描述的说明如下:
- 200 OK:客户端
请求成功
。 - 400 Bad Request:
客户端请求有语法错误
,不能被服务器所理解
。 - 401 Unauthorized:
请求未经授权
,这个状态代码必须和WWW-Authenticate报头域一起使用。 - 403 Forbidden:
服务器收到请求
,但是拒绝提供服务
。 - 404 Not Found:
请求资源不存在
,举个例子:输入了错误的URL
。 - 500 Internal Server Error:
服务器发生不可预期的错误
。 - 503 Server Unavailable:服务器当前
不能处理客户端的请求
,一段时间后可能恢复正常
,举个例子:HTTP/1.1 200 OK(CRLF)。
2.2 响应头
2.3 响应实体内容:
服务器发给浏览器,要让浏览器显示的内容
(html,js,css,图片,数据等信息)。
下面给出一个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>
3 关于HTTP请求GET和POST的区别
1、GET提交,请求的数据会附在URL之后
(就是把数据放置在HTTP协议头<request-line>中),以?分割URL和传输数据
,多个参数用&连接
;例如:login.action?name=hyddd&password=idontknow&verify=%E4%BD%A0 %E5%A5%BD
。如果数据是英文字母/数字,原样发送
,如果是空格,转换为+
,如果是中文/其他字符
,则直接把字符串用BASE64加密
,得出如: %E4%BD%A0%E5%A5%BD,其中%XX中的XX为该符号以16进制表示的ASCII
。
POST提交:把提交的数据
放置在是HTTP包的包体请求体<request-body>
中。上文示例中红色字体标明的就是实际的传输数据
因此,GET提交的数据会在地址栏中显示出来,而POST提交,地址栏不会改变。
2、传输数据的大小
:首先声明,HTTP协议没有对传输的数据大小进行限制,HTTP协议规范也没有对URL长度进行限制。 而在实际开发中存在的限制主要有:
GET
:特定浏览器和服务器对URL长度有限制
,例如IE对URL长度的限制是2083字节(2K+35)。对于其他浏览器,如Netscape、FireFox等,理论上没有长度限制,其限制取决于操作系统的支持。因此对于GET提交时,传输数据就会受到URL长度的限制。一般限制在1k字节
。
POST
:由于不是通过URL传值,理论上数据不受限。但实际各个WEB服务器会规定对post提交数据大小进行限制,Apache、IIS6都有各自的配置。
3、安全性
:POST的安全性要比GET的安全性高
。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上
,因为(1)登录页面有可能被浏览器缓存
, (2)其他人查看浏览器的历史纪录
,那么别人就可以拿到你的账号和密码了。
以下转自:
HTTP首部字段向请求和响应报文中添加了一些附加信息。本质上来说,它们只是一些名/值对的列表。头部和协议配合工作,共同决定了客户端和服务器能做什么事情。
4 头部的分类:
4.1 通用头部:
既可以出现
在请求报文
中,也可以出现在响应报文
中,它提供了与报文相关的最基本的信息
。
Connection
:允许客户端和服务器指定与请求/响应连接有关的选项
(标识:长短连接
)
Date
:提供日期和时间标志,说明报文是什么时间创建的
MIME-Version:给出了发送端使用的MIME版本
Trailer:如果报文采用了分块传输编码方式,就可以用这个首部列出位于报文拖挂部分的首部集合
Transfer-Encoding
:告知接收端为了保证报文的可靠传输
,对报文采用了什么编码方式
Update
:给出了发送端可能想要“升级”使用的新版本或协议
Via
:显示了报文经过的中间节点(代理、网关)
Cache-Control:用于随报文传送缓存指示
4.2 请求头部:
请求头部是只在 请求报文 中有意义的头部
。用于说明是谁或什么在发送请求、请求源自何处,或者客户端的喜好及能力
Client-IP
:提供了运行客户端的机器的IP地址
From:提供了客户端用户的E-mail地址
Host
:给出了接收请求 的 服务器 的 主机名和端口号
Referer:提供了包含当前请求URI的文档的URL
UA-Color:提供了与客户端显示器的显示颜色有关的信息
UA-CPU
:给出了客户端CPU的类型或制造商
UA-OS
:给出了运行在客户端机器上的操作系统名称及版本
UA-Pixels:提供了客户端显示器的像素信息
User-Agent:将发起请求的应用程序名称告知服务器
Accept
:告诉服务器能够发送哪些媒体类型
Accept-Charset
:告诉服务器能够发送哪些字符集
Accept-Encoding
:告诉服务器能够发送哪些编码方式
Accept-Language
:告诉服务器能够发送哪些语言
TE:告诉服务器可以使用那些扩展传输编码
Expect:允许客户端列出某请求所要求的服务器行为
Range:如果服务器支持范围请求
,就请求资源的指定范围
If-Match:如果实体标记与文档当前的实体标记相匹配,就获取这份文档
If-Modified-Sinec
:除非在某个指定的日期之后资源被修改过,否则就限制这个请求
If-None-Match
:如果提供的实体标记与当前文档的实体标记不相符,就获取文档
If-Range:允许对文档的某个范围进行条件请求
If-Unmodified-Since:除非在某个指定日期之后资源没有被修改过,否则就限制这个请求
Authorization:包含了客户端提供给服务器,以便对其自身进行认证的数据
Cookie
:客户端用它向服务器传送数据
Cookie2
:用来说明请求端支持的cookie版本
Max-Forward:在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数
Proxy-Authorization:这个首部在与代理进行认证时使用的
Proxy-Connection:这个首部是在与代理建立连接时使用的
4.3 响应头部:
响应头部为客户端提供了一些额外信息
,比如谁在发送响应
、响应者的功能
,甚至与响应相关的一些特殊指令
Age:(从最初创建开始)响应持续时间
Public
:服务器为其资源支持的 请求方法列表
Retry-After:如果资源不可用的话,在此日期或时间重试
Server
:服务器应用程序软件的名称和版本
Title:对HTML文档来说,就是HTML文档的源端给出的标题
Warning:比原因短语更详细一些的警告报文
Accept-Ranges:对此资源来说,服务器可接受的范围类型
Vary:服务器会根据这些首部的内容挑选出最适合的资源版本发送给客户端
Proxy-Authenticate:来自代理的对客户端的质询列表
Set-Cookie
:在客户端设置数据
,以便服务器对客户端进行标识
Set-Cookie2
:与Set-Cookie类似
WWW-Authenticate:来自服务器的对客户端的质询列表
4.4 实体首部:
描述主体的 长度 和 内容,或者 资源自身
Allow
:列出了可以对此实体执行的请求方法
Location:告知客户端 实体实际上位于何处
,用于将接收端定向到资源的位置(URL)上去
Content-Base:解析主体中的相对URL时使用的基础URL
Content-Encoding
:对主体执行的任意编码方式
Content-Language
:理解主体时最适宜使用的自然语言
Content-Length
:主体的长度
Content-Location
:资源实际所处的位置
Content-MD5:主体的MD5校验和
Content-Range:在整个资源中此实体表示的字节范围
Content-Type
:这个主体的对象类型
ETag:与此实体相关的实体标记
Expires:实体不再有效,要从原始的源端再次获取实体的日期和时间
Last-Modified
:这个实体最后一次被修改的日期和时间