Http协议
HTTP(TyperText Transport Protocol)协议是互联网上应用最广泛的一种网络协议标准。所有WWW文件都必须遵守这个标准。目前普遍使用的版本是 HTTP1.1。
HTTP协议的特点:
- 支持C/S模式。
- 简单快速。客户端向服务器请求服务时只需要传送请求方法和路径。
- 灵活。HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
- 无连接。无连接的含义是限制每次连接只处理一个请求。服务器收到客户端的请求,并收到客户端的应答后即断开连接。
- 无状态。HTTP协议是无状态协议。无状态是指协议对于事物处理没有记忆能力。
HTTP报文格式
HTTP报文是面向文本的,报文中的每一个字段都是一些ASCII码串,各个字段的长度是不确定的。HTTP有两类报文:即请求报文和响应报文。
1、请求报文
一个HTTP请求报文由 请求行(request line)、请求头部(header)、空行和请求数据4部分组成。
请求报文的一般格式如下图:
1).请求头
请求头由请求方法字段、URL字段和HTTP协议版本字段 组成,他们之间用空格分隔。
例如:GET /index.html HTTP1.1
常见的HTTP请求方法有如下几种
请求方法 | 含义 |
---|---|
GET | 请求获取Request-URL所标识的资源 |
POST | 在Request-URL锁标识的资源后附加新的数据 |
HEAD | 请求获取由Request—URL所标识的资源的响应消息报头 |
PUT | 请求服务器存储一个资源,并用Request-URL作为标识符 |
DELETE | 请求服务器删除Request-URL所标识的资源 |
TRACE | 请求服务器回送收到的请求信息,主要用于测试或诊断 |
CONNECT | 保留将来使用 |
OPTIONS | 请求查询服务器性能,或查询与资源相关的选项或需求 |
- GET
GET方法要求服务器将URL定位的资源放在响应报文的数据部分,回送给客户端。使用GET时请求参数和对应的值附加在URL后面,利用一个“?”分隔,参数之间使用“&”分隔。传参数的长度受限制。显然这种方式不适合传输私密数据,另外由于不同浏览器对地址的字符限制有所不同,一般最多只能是1024个字符。所以如果传输大量的数据时也不适合使用GET。
- POST
POST方式将请求参数封装在HTTP请求数据中,以名称/值形式出现,可以传输大量的数据,POST方式对传输数据的大小没有限制,而且也不会显示在URL中。
- HEAD
HEAD就像GET,只不过服务器收到HEAD请求后只返回响应头,而不会返回响应内容。当我们只需要查询每个页面的状态时使用HEAD是非常高效的。因为传输过程中省去了页面内容。
POST与PUT的区别:
在HTTP中,PUT被定义为idempotent的方法,POST则不是,这是一个很重要的区别。
如果一个方法重复执行多次,产生的效果是一样的,那就是idempotent的。
在编程中.一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。幂等函数,或幂等方法,是指可以使用相同参数重复执行,并能获得相同结果的函数。这些函数不会影响系统状态,也不用担心重复执行会对系统造成改变.
举一个简单的例子,假如有一个博客系统提供一个Web API,模式是这样http://superblogging/blogs/post/{blog-name},
很简单,将{blog-name}替换为我们的blog名字,往这个URI发送一个HTTP PUT或者POST请求,HTTP的body部分就是博文,这是一个很简单的REST API例子。我们应该用PUT方法还是POST方法?取决于这个REST服务的行为是否是idempotent的,假如我们发送两个
http://superblogging/blogs/post/Sample
请求,服务器端是什么样的行为?如果产生了两个博客帖子,那就说明这个服务不是idempotent的,因为多次使用产生了副作用了嘛;如果后一个请求把第一个请求覆盖掉了,那这个服务就是idempotent的。前一种情况,应该使用POST方法,后一种情况,应该使用PUT方法。
2)、请求头部
请求头部由关键字/值对组成,每行一对,关键字和值用英文冒号“:”分隔。请求头部通知服务器有关于客户端请求的信息,典型的请求头有:
User-Agent:产生请求的浏览器类型。
Accept:客户端可识别的内容类型列表。
Host:请求的主机名,允许多个域名同处一个IP地址,即虚拟主机。
3)、空行
最后一个请求头之后是一个空行,发送回车符和换行符,通知服务器以下不再有请求头。
4)、请求数据
请求数据不在GET方法中使用,而是在POST方法中使用。POST方法适用于需要客户填写表单的场合。与请求数据相关的最常使用的请求头是Content-Type和Content-Length。
2、HTTP响应报文
HTTP响应报文也是由4部分组成,分别是:状态行、消息头部、空行和响应正文。格式如下图:
正如你所见,在响应中唯一真正的区别在于第一行中用状态信息代替了请求信息。状态行(status line)通过提供一个状态码来说明所请求的资源情况。
状态行格式如下:
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)。
3、HTTP消息报头
如前所述,HTTP消息由客户端到服务器的请求和服务器到客户端的响应组成。请求消息和响应消息都是由开始行(对于请求消息开始行就是请求行,对于响应消息,开始行是状态行)、消息头部(可选)、空行(只有CRLF的行)、消息正文4部分组成。其中消息报头包括普通报头、请求报头、响应报头、实体报头。消息报头由头部名/值对组成,每行一对,头部字段名和值用“:”分隔。其中消息报头头部字段名是大小写无关的。报头描述了客户端或者服务器的属性,被传送的资源以及实体连接。
4种不同类型的消息报头分述如下:
普通报头:即可用于请求,也可用于响应,不用于被传输实体,只用于传输消息,是作为一个整体而不是特定的资源与事物关联。
请求报头:允许客户端传递关于自身的信息和希望响应的形式。请求报头通知服务端有关客户端的请求信息。典型的有如下几种:
User-Agent:包含产生请求的操作系统,浏览器类型等信息
Accept:客户端可识别内容类型列表,用于指定客户端接受那些类型的信息。
Host:请求主机名,允许多个域名同处一个IP地址,即虚拟主机
- 响应报头:服务器用于传递自身信息的响应。如:
Location:用于重定向接收者到一个新的位置。Location响应域名常用在更换域名的时候
Server:包含服务器用来处理请求的系统信息,与User-Agent请求报头是相对应的。
- 实体报头:定义被传送资源的信息。即可用于请求,也可用于响应。请求和响应消息都可以传送一个实体。如:
Content-Encoding:被用作媒体类型的修饰符,它的值指示了已经被应用到实体正文的附加内容的编码。因而要获得Content-Type报头中所引用的媒体类型,必须采用响应的解码机制。
Content-Language:描述了资源所用的自然语言。没有设置该选项则认为实体内容将提供给所用语言阅读。
Content-Length:用于致命实体正文的长度,以字节方式存储十进制来表示
Last-Modified:用于指示资源的最后修改日期和时间。
注意:URL中的一些字符有特殊的含义,基本编码规则如下:
空格换成(+)号;正斜杠(/)分隔目录和子目录;问好(?)分隔URL和查询;百分号(%)指定特殊字符;#号指定书签;&号分隔参数,有时也做为连接符。