《HTTP权威指南》学习笔记-HTTP报文
来源:互联网 发布:淘宝直通车黑车 编辑:程序博客网 时间:2024/04/28 04:04
上一篇文章写了HTTP协议中的基本概念和URL,这一篇要来讲一下HTTP协议中的报文本身。如果说HTTP是Internet的信使,那么HTTP报文就是它用来搬东西的包裹了。本文包含以下内容:
- HTTP报文的组成部分
- HTTP报文的语法结构
- HTTP方法
- HTTP状态码
- HTTP首部(Header)详解
- 自己的一些读后的总结和感悟
HTTP报文的语法
HTTP是基于请求/响应模式的通信协议,所有的HTTP报文可以分为请求报文和响应报文。请求报文会向Web服务器请求一个动作,响应报文会将请求结果返回给客户端。
语法结构
请求报文和响应报文的基本结构非常类似,下面是请求报文的语法结构:
<method> <request-url> <version><headers><entity-body>
下面是响应报文的语法结构:
<version> <status-code> <reason-phrase><headers><entity-body><headers><entity-body>
可以看出,请求报文和响应报文的语法仅仅在起始行(第一行)处有所不同。下面对报文的各个部分做简要描述。
方法(method):表示客户端对资源执行的动作,是一个单独的动词,比如GET、POST等。
请求资源的URL(request-url):表示请求的资源的URL,关于URL的知识已经在上一篇文章中介绍了。
协议版本(version):表示所使用的HTTP的协议版本,其格式为:HTTP/.,其中major表示主版本号,minor表示次版本号。
状态码(status-code):表示请求过程中所发生的情况,是一组三位数的数字。关于状态码会在接下来的内容介绍。
原因短语(reason-phrase):状态码的可读版本,是对状态码的解释,对人类来说是可读的。
首部(header):表示请求或响应中的附加信息,可以有零个或多个首部,每个首部项都是形如name: value
的字符串,每个首部项后面都以CRLF(回车+换行)结束。
实体的主体部分(entity-body):包含任意格式的数据块,是Web应用的主体内容。
HTTP报文的组成部分
HTTP报文包括请求报文和响应报文,由起始行(start line)、首部(header)和主体(body)三个部分组成,其中起始行和首部是必有的,主体部分是可选的。
起始行(start line)
所有的HTTP报文都以一个起始行作为开始,请求报文起始行说明要做什么事,响应报文的起始行说明发生了什么事。
请求起始行
请求报文请求对服务器中的资源进行一些操作,包含请求方法,请求URL,在有些版本的协议中还需要加入HTTP协议的版本。一个典型的请求报文的起始行如下:
GET /test/hi-there.txt HTTP/1.1
注意,URL部分并不包含主机信息,不是完整的路径,而是具体服务器上的资源路径。主机(host)的信息会包含到首部中,首部会在接下来的内容中介绍。
响应起始行
响应报文承载着响应状态信息和操作产生的结果数据,并返回给客户端。响应起始行包含着HTTP版本、数字状态码以及描述操作状态的文本形式的原因短语,每一部分之间用空格分隔。一个典型的响应报文的起始行如下:
HTTP/1.1 200 OK
首部(header)
首部是向请求或响应报文中添加的附加信息,本质上来说,是一些key:value列表。下面列出了一些平常常见的首部。
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8Accept-Encoding:gzip, deflate, sdchAccept-Language:zh-CN,zh;q=0.8,en;q=0.6,ja;q=0.4,zh-TW;q=0.2Cache-Control:max-age=0Host:www.csdn.netUser-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36
由于首部全部都是文本,所以首部是可扩展的,只要服务端支持即可。首部字段可以分成下面几类:
- 通用首部:可以同时用于请求和响应报文,比如Date首部。
- 请求首部
- 响应首部
- 实体首部
- 扩展首部
首部内容是HTTP中的重点内容,在实际开发过程中需要时常与之接触,详细内容将接下来的单独介绍。
主体(body)
主体是HTTP报文实际负载的内容,具体来说,就是应用程序数据。Web开发者要做工作就是编写这部分内容。主体类型非常丰富,可以是:图片、视频、HTML文档、电子邮件等。所以HTTP协议为什么将超文本传输协议,就是因为其负载的内容并不局限与文本。主体的类型有上层开发者负责,HTTP协议对它并没有做很多约束和限制。
HTTP方法
方法告知服务器要做什么操作,位于请求报文起始行的开始位置。HTTP协议中规定的主要方法有:
- GET:最常用的方法,用户请求服务器上的某个资源。
- HEAD:与GET方法的行为很类似,但在服务器响应中仅返回首部,不会返回主体数据。
- PUT:与GET方法相反,PUT回向服务器中写入文档。PUT的语义是让服务器用请求的主体部分来创建一个由所请求的URL命名的新文档。或者,如果那么URL所对应的资源已经存在的话,这个请求中的主体来替换原来的文档。
- POST:向服务器中发送数据。实际上,通常会用它来支持HTML表单。1
- DELETE:请服务器删除请求URL所指定的资源。
- TRACE:用于“环回”测试和诊断。客户端请求可能要穿过防火墙、代理、网关等中间节点才能达到最终的目的服务器,每个中间节点都可能会修改原始的HTTP请求,TRACE方法允许客户端看到它的请求最终变成了什么样子。下图是一个TRACE过程示例。尽管TRACE可以很方便的诊断,但它也有缺点。它假定中间节点对不同的类型的请求(比如不同的方法)会做相同的处理,实际上,不同类型的请求可能会做不同的处理,譬如,将POST请求直接发到应用服务器,而将GET请求发往缓存服务器。TRACE请求中不能带有实体的主体部分,响应报文中的主体部分是服务器收到的请求的精确副本。
- OPTIONS:请求服务器告知其支持的各种功能。可以询问服务器通常支持哪些方法,或者哪些特殊资源支持哪些方法。下面是一个OPTIONS方法示例:
下图是对HTTP协议中主要方法汇总:
上面的方法中,GET和HEAD方法是安全的方法,使用这些方法不会产生什么动作。POST等方法不是安全方法,POST方法会在服务器端生成新数据。假设是个请求扣款操作,多次执行POST操作有可能(如果服务端写的非常糟糕的话)会导致重复扣款。
HTTP状态码
HTTP中状态码的作用是告诉客户端发生了什么事,状态码位于响应报文的起始行中。HTTP中状态码使用三位数字来表示,根据最高位数据可以分为下面几类:
下面来介绍一下使用开发中比较常用的状态码。
1、 100~199(信息性状态码)
HTTP/1.1向协议中引入的信息性状态码,由于对其复杂性和感知价值存在争议,因为使用受到限制。
2、 200~299(成功状态码)
客户端发起请求时,这些请求通常是成功的。这一段状态码表示成功的状态,分别对应不同类型的请求。
3、 300~399(重定向状态码)
重定向响应码要么告知客户端使用替代位置来访问他们所感兴趣的资源,那么提供一个替代的响应而不是替代的内容。如果原来的资源已经被移走,可发送一个重定向状态码和一个可选的Location首部来告知客户端资源已经被移走了。
从上表中可以看出,302、303、307的状态码功能非常相似,它们有些细微的差别,大部分差别来源于HTTP/1.0和HTTP/1.1应用程序对这些状态码的处理不同。
当HTTP/1.0客户端发起POST请求,并在收到302响应时,它会接受Location首部的重定向URL,并向那么URL发起一个GET请求(而不是向原始请求的那样发起POST请求)。问题在于,在HTTP/1.1中使用303状态码实现了与HTTP/1.0中的302状态码的相同功能。为了避开这个问题,HTTP/1.1规范指出,对于HTTP/1.1客户端,用307状态码取代302状态码来进行临时重定向。这个服务器就把302状态码保留起来,为HTTP/1.0可以使用了。
这样一来,服务器要选择适当的重定向状态码放入重定向响应中,就需要查看客户端的HTTP版本了。
4、 400~499(客户端错误状态码)
有时客户端会发送一些服务器无法处理的请求,比如格式错误的请求报文,或者最常见的是,请求一个不存在的URL。很多客户端错误都是有浏览器来处理的,甚至不会打扰到用户。只有少量的错误,比如404会来到用户的面前。
5、 500~599(服务器出错状态码)
如果客户端发送了一个请求,服务端自身发生了错误,就会返回这么段的状态码。
下面自己试着总结一下这些HTTP状态码:
- 4XX错误种类最多。客户端是软件开发者能掌控的最弱的环节,也是可能出错最多的地方;
- 有些状态码的语义比较模糊(比如400、500),通用性很强,不利于定位错误。所以,在实际开发中应该尽量少用这种语义模糊的状态码。
- 有些状态码语义有些重叠和相似。比如405和501这两个状态码,虽然405的错误更加明确,但都是表示服务端无法处理这个请求。那么到底是客户端使用了未实现或未允许的方法呢?还是服务器无法处理这个请求呢?语义的重叠带来了开发中的选择困难。
HTTP首部详解
首部和方法配合,共同绝对了客户端和服务端能够做什么。在请求和响应报文中都可以用首部来提供信息,按照首部所处的端点和位置可以将首部分成5类:
- 通用首部:客户端和服务端都可以使用的首部。
- 请求首部:请求报文中特有的首部。
- 响应首部:响应报文中特有的首部。
- 实体首部:对应于实体主体部分的首部。
- 扩展首部:应用开发者自己创建的首部。
通用首部
通用首部提供了一些最基本的信息,下表列出了一些常用的通用首部。
请求首部
请求首部是只在请求报文中有意义的首部。用于说明是谁或什么在发送请求、请求源于何处。可以根据首部的功能来对请求首部进行分类。
1、 信息性请求首部
2、 Accept首部
Accept首部为客户端提供了一种将其喜好和能力告知服务器的方式。可以告知服务端它们想要什么,可以使用什么,以及不想要什么。服务端可以根据这些首部,来做发送的内容作出更加明智的决定。
3、 条件请求首部
通过条件请求首部,客户端可以为请求加上限制,要求服务器在对请求响应之前,确保某个条件为真。
4、 安全请求首部
HTTP本身就支持一种简单的机制,可以对请求进行质询/响应认证。客户端在请求资源时,需要带上安全请求首部才能获取特定的资源。
5、 代理请求首部
响应首部
响应首部为客户端提供一些额外信息,比如谁在发送响应,响应者的功能,甚至与响应相关的一些特殊指令。这些首部有利于客户端处理响应,并在将来发起跟高的请求。
1、 信息性响应首部
2、 协商响应首部
3、 安全响应首部
实体首部
有很对首部用来描述HTTP的负荷,由于请求和响应中都可能包含实体部分,所以在这两张报文中都可能出现这类首部。
实体首部提供了实体及其内容的的大量信息,从有关对象类型的信息,到能够对资源使用的各种有效的请求方法。总之,实体首部可以告知报文的接受者它在对什么进行处理。
1、 信息性实体首部
2、 内容实体首部
内容首部提供了与实体内容有关的特定信息,说明了其类型、尺寸以及处理它所需的其他有用信息。
3、 实体缓存首部
缓存首部说明了如何或什么时候进行缓存。
读后反省
读了本节内容,再联系到自己在实际开发过程中对HTTP协议的运用,发现之前用的不正确、不合理。下面是自己总结的用的不正确的地方:
- 除了post、get方法外的方法,基本上没有用过其他HTTP方法。HTTP是应用层协议,与自己开发的应用程序属于同一个网络层次。只不过它给我们解决了网络应用程序中的通用性问题,让应用软件开发者可以将重心放在应用内容本身。既然HTTP协议本身已经定义了这么多的执行动作的方法,就不应该弃之不用。必然要删除某个资源,完全可以使用delete方法来标志删除动作。 最近在研究rest这种Web应用设计思想,它可以使得应用程序充分运用HTTP协议。
- URL误用。URL是资源的唯一标识符,指示资源的位置和获取方式。从语言词性层面来说,这样的描述性短语应该是一个名词性短语,所以诸如www.xx.com/getUsers、/deleteUser?id=11之类URL都属于误用。
- 很少使用除了200、404、500以外的状态码来描述响应状态。既然HTTP协议与应用数据属于同一个网络层次,如果HTTP中定义的状态码足以描述当前的状态,就应该优先使用它们,而不是使用自定义的状态。
在这篇文章以前,自己已经阅读过HTTP状态码、首部等内容很多次了,但就是记不住。读一遍记不住,读十遍也就是那样。但是,自己这么完整的复写过一遍之后,对整个HTTP协议细节有了更深的认识,而且也能够勉强记住了。好记性不如烂笔头,确实是这么一个道理。虽然把人家书上的内容是照搬了过来,相当了又重复造了一遍轮子,但是对笔者来说却相当收益。技术提高没有什么捷径可走,要的就是更多地去实践,造轮子不失为一种技术提高的有效办法。
总结
本文是有关HTTP学习的第二篇的文章,主要介绍了HTTP协议中的报文,包括报文组成、语法结构、方法、状态码和详细的首部介绍。内容以《HTTP权威指南》为主,同时加入了自己的理解。在文章的末尾谈了谈阅读和写完本章内容之后的感想,以及对自己今后开发上可能的帮助。同时也反思一下自己本身的不足,要好好加油才是!本文历时了2个多星期才写完,不是因为时间不够,实在是懒癌症太厉害了。而且,工作上也不是很如意,有时候回家后啥都不想干。最后还是写完了,坚持就是胜利。Keep learning!
- 注意与PUT方法的区别,POST向服务器发送数据,PUT用于向服务器中的资源(比如文件)中存储数据。 ↩
- 《HTTP权威指南》学习笔记-HTTP报文
- 《HTTP权威指南》学习笔记(三)—HTTP报文
- 《HTTP权威指南》学习笔记(3)第3章HTTP报文(关键词:计算机网络/HTTP/HTTP报文)
- HTTP权威指南学习笔记
- HTTP权威指南学习笔记
- 《HTTP权威指南》学习笔记
- HTTP权威指南学习笔记
- 《HTTP权威指南》读书笔记---HTTP报文
- HTTP报文格式-摘自<HTTP权威指南>
- 2.http权威指南:HTTP报文
- HTTP权威指南读书笔记三:HTTP报文
- HTTP报文(http权威指南第三章)
- http权威指南笔记
- HTTP权威指南 笔记
- HTTP权威指南笔记
- HTTP权威指南笔记
- http权威指南学习笔记(二)
- 《HTTP权威指南》学习笔记(一)
- 河内之塔(汉诺塔) java实现
- android 友盟分享一直返回分享取消
- SyntaxError: Non-ASCII character ‘\xe5′ in file 关于python中的编码问题
- MFC控件系列之一:Edit Control用法
- 不同区域控制器名称相同出错的解决方法(备忘)
- 《HTTP权威指南》学习笔记-HTTP报文
- 16-Ajax学习之什么是Ajax,Ajax原理
- 属性动画+贝塞尔曲线实现落叶效果~~~(@_@;)
- aaaa
- swift手记-2
- Activity切换动画overridePendingTransition
- 安卓事件拦截机制分析
- HDU 1160 FatMouse's Speed
- Java接口与抽象类的区别