客户端向服务器发送HTTP请求,服务器会在HTTP响应中送回所请求的数据。
HTTP客户端和HTTP服务器共同构成了万维网的基本组件。
Web服务器是Web资源的宿主,Web资源是Web内容的源头。
最简单的资源就是Web服务器文件系统中的静态文件。资源还可以是根据需要生成内容的软件程序。
URI:服务器资源名称为统一资源标识符
http://www.joes-hardware.com/specials/saw-blade.gif
URI有两种形式分别为:URL和URN
URL:统一资源定位符
http----使用HTTP协议
www.joes-hardware.com----进入www.joes-hardware.com
/specials/saw-blade.gif----获取名为/specials/saw-blade.gif的资源
几乎所有的URI都是URL。
大部分URL都遵循一种标椎格式,这种格式包含三个部分
1.URL的第一部分被称为方案,说明了访问资源所使用的的协议类型,这部分通常就是HTTP协议(http://)
2.第二部分给出了服务器的因特网地址(比如www.joes-hardware.com)
3.第三部分指定了Web服务器上的某个资源(比如 /specials/saw-blade.gif)
URN:统一资源名。URN是作为特定内容的唯一名称使用的,与目前的资源所在地无关。
不论因特网标准文档RFC2141位于何处,都可以用下列URN来命名:urn:ietf:rfc:2141
URN仍然处于试验阶段,还未大范围使用。
一个HTTP事务由一条请求命令和一个响应结果组成,这种通信是通过名为HTTP报文的格式化数据块进行的。
HTTP请求方法:GET 从服务器向客户端发送命名资源
PUT 将来自客户端的数据存储到一个命名的服务器资源中去
DELETE 从服务器中删除命名资源
POST 将客户端数据发送到一个服务器网关应用程序
HEAD 仅发送命名资源响应中的HTTP首部
状态码:
200 OK,文档正确返回
302 重定向,到其他地方去获取资源
404 无法找到这个资源
从Web客户端发往Web服务器的HTTP报文称为请求报文,从服务器发往客户端的报文称为响应报文,此外没有其他类型的HTTP报文。
HTTP报文格式:
1.起始行:报文的第一行就是起始行,在请求报文中用来说明要做什么,在响应报文中说明出现了什么情况。
2.首部字段:起始行后面有零个或多个首部字段,每个首部字段都包含一个名字和一个值,为了便于解析,两者之间用冒号来分隔。首部以一个空行结束,添加一个首部字段和添加新行一样简单。
3.主体:空行之后就是可选的报文主体了,其中包含了所以类型的数据。请求主体中包括了要发送给Web服务器的数据;响应主体中装载了要返回给客户端的数据。
起始行和首部都是文本形式且都是结构化的,而主体则不同,主体中可以包含任意的二进制数据。
简单的文本结构组成的HTTP报文:
HTTP是个应用层协议,把联网的细节交给了因特网传输协议TCP/IP。
TCP提供了:
无差错的数据传输
按序传输(数据总是会按照发送的顺序到达)
未分段的数据流(可以在任意时刻以任意尺寸将数据发送出去)
只要建立了TCP连接,客户端和服务器之间的报文交换就不会丢失,不会被破坏,也不会在接收时出现错序了。
HTTP网络协议栈:
Telnet程序可以将键盘连接到某个目标TCP端口,并将此TCP端口的输出回送到显示屏上,Telnet常用于远程终端会话,但它几乎可以连接所有的TCP服务器,包括HTTP服务器。
代理:位于客户端和服务器之间的HTTP中间实体
缓存:HTTP的仓库,使常用页面的副本可以保存在离客户端更近的地方
网关:连接其他应用程序的特殊Web服务器
隧道:对HTTP通信报文进行盲转发的特殊代理。常见的用途是通过HTTP连接承载加密的安全套接字层(SSL)流量。
Agent代理:发起自动HTTP请求的半智能Web客户端
通用URL组件
方案:使用什么协议
http://www.joes-hardware.com/specials/saw-blade.gif 中的http
用户,密码:很多服务器要求输入用户名和密码才会允许用户访问数据。
例子:
ftp://ftp.prep.ai.mit.edu/pub/gnu
ftp://[email protected]/pub/gnu
ftp://username:[email protected]/pub/gnu
主机,端口:提供了哪台机器装载了资源,以及在那台机器的什么地方可以找到对目标资源进行访问的服务器。
示例:http://www.joes-hardware.com:80/index
http://161.58.228.45:80/index
路径:说明了资源位于服务器的什么地方。路径通常很像一个分级的文件系统路径。
示例:http://www.joes-hardware.com/specials/saw-blade.gif 中的/specials/saw-blade.gif
参数:为了向应用程序提供它们所需的输入参数,以便正确地与服务器进行交互。
示例:ftp://ftp.prep.ai.mit.edu/pub/gnu;type=d中的type=d
查询:很多资源,比如数据库服务,都是可以通过提问题或进行查询来缩小所请求资源类型范围的。
示例:http://www.joes-hardware.com/specials/saw-blade.gif?item=13721&color=blue中的?item=13721&color=blue
片段:为了引用部分资源或资源的一个片段,URL支持使用片段组件来表示一个资源内部的片段。
示例:ftp://ftp.prep.ai.mit.edu/pub/gnu#drills中的#drills
URL有两种方式:绝对的和相对的。
绝对URL中包含有访问资源所需的全部信息。
相对URL是不完整的,要从相对URL中获取访问资源所需的全部消息,就必须相对于另一个,被称为其基础的URL进行解析。
绝对的:http://www.joes-hardware.com/tools.html
相对的:./hammers.html
相对URL和基础URL转换成绝对URL如图:
路径为./hammers.html,基础URL为http://www.joes-hardware.com/tools.html。
方案为空,沿着图表的左半边向下处理,继承基础URL方案(HTTP)。
至少一个组件非空,一直处理到底端,继承主机和端口组件。
将来自相对URL的组件与我们继承来的组件合并起来,得到新的绝对URL:http://www.joes-hardware.com/hammers.html
编码字符示例:
~ http://www.joes-hardware.com/%7Ejoe
空格 http://www.joes-hardware.com/more%20tools.html
% http://www.joes-hardware.com/100%25satisfaction.html
常见方案格式:
1.http :超文本传输协议
示例 http://www.joes-hardware.com/tools.html 默认端口 80
2.https :与http是一对,唯一的区别在于方案https使用了网景的SSL,SSL为HTTP连接提供了端到端的加密机制
示例 https://www.joes-hardware.com/tools.html 默认端口 443
3.mailto :指向的是E-mail地址。
示例 mailto:[email protected]
4.ftp :文件传输协议可以用来从FTP服务器上下载或向其上传文件,并获取FTP服务器上的目录结构内容的列表。
示例 ftp://anonymous:joe%[email protected]:21/pub/gnu/ 默认端口 21
5.rtsp,rtspu: RTSP是可以通过实时流传输协议,解析音频视频媒体资源的标识符。
rtspu中的u表示它是使用UDP协议来获取资源的。
示例 rtsp://www.joes-hardware.com:554/interview/cto_video 默认端口 554
6.file:表示一台指定主机上可直接访问的文件。
示例 file://OFFICE-FS/policies/casual-fridays.doc
7.news:根据RFC1036的定义,用来访问一些特定的文章或新闻组。newsURL自身包含的信息不足以对资源进行定位。
示例 news:rec.arts.startrek
8.telnet:用于访问交互式业务。它表示的并不是对象自身,而是可通过telnet协议访问的交互式应用程序。
示例 telnet://slurp:[email protected]:23/
HTTP报文是在HTTP应用程序之间发送的数据块。这些数据块以一些文本形式的元信息开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。
不管是请求报文还是响应报文,所有报文都会向下游流动。所有报文的发送者都在接受者的上游。
每条报文都包含一条来自客户端的请求,或者一条来自服务器的响应。
由三个部分组成,对报文进行描述的起始行,包含属性的首部块,以及可选的包含数据的主体部分。
起始行和首部是由行分隔的ASCII文本。每行都以一个由两个字符组成的行终止序列作为结束,其中包括一个回车符和一个换行符。行终止序列可以写作CRLF。
稳健的应用程序也应该接受单个换行符作为行的终止。
注意:一组HTTP首部总是应该以一个空行结束,甚至即使没有首部和实体的主体部分也应如此。
方法,请求URL,版本,状态码,原因短语,首部,实体的主体部分
1.请求行:请求报文请求服务器对资源进行一些操作,请求报文的起始行称为请求行,包含了一个方法和一个请求URL,这个方法描述了服务器应该执行的操作,
请求URL描述了要对哪个资源执行这个方法。请求行中还包含了HTTP的版本,用来告知服务器,客户端使用的是哪种HTTP。所有这些字段都由空格符分隔。
示例:GET /testhi-there.txt HTTP/1.1 一个方法GET 一个请求URL /testhi-there.txt HTTP的版本HTTP/1.1
2.响应行:响应报文承载了状态信息和操作产生的所有结果数据,将其返回给客户端。响应报文的起始行称为响应行,包含了响应报文使用的HTTP版本、数字状态码,
以及描述操作状态的文本形式的原因短语。所有这些字段都由空格符分隔。
示例:HTTP/1.0 200 OK HTTP版本HTTP/1.0 数字状态码200 原因短语OK
3.方法:请求的起始行以方法作为开始,方法用来告知服务器要做些什么。
示例:GET /testhi-there.txt HTTP/1.1 GET方法
** 常用HTTP方法:**
4.状态码:是用来告诉客户端,发生了什么事情。
200–299之间的状态码表示成功。
300–399之间的状态码表示资源已经被移走。
400–499之间的状态码表示客户端请求出错了。
500–599之间的状态码表示服务器出错了。
100–199信息状态码
200–299成功状态码
300–399重定向状态码
400–499客户端错误状态码
500–599服务器错误状态码
5.原因短语:原因短语和状态码是成对出现的。原因短语是状态码的可读版本。
6.版本号:版本号会以HTTP/x.y的形式出现在请求和响应报文的起始行中。
首部跟在起始行后面可以有零个、一个或多个HTTP首部字段。
HTTP首部字段向请求和响应报文中添加了一些附加信息。本质上来说,它们只是一些名、值对的列表。
示例:Content-length:19
1.首部分类:
通用首部:既可以出现在请求报文中,也可以出现在响应报文中。
请求首部:提供更多有关请求的信息。
响应首部:提供更多有关响应的信息。
实体首部:描述主体的长度和内容,或者资源本身。
扩展首部:规范中没有定义的新首部。
2.首部延续行
将长的首部行分为多行可以提高可读性,多出来的每行前面至少要有一个空格或tab
示例:Server:Test Server
Version 1.0
常见首部实例:
HTTP报文的第三部分是可选的实体主体部分,实体的主体是HTTP报文的负荷,就是HTTP要传输的内容。
1.GET:是最常用的方法。通常用于请求服务器发送某个资源。
GET示例:
2.HEAD:与GET方法行为类似,但服务器在响应中只返回首部。不会返回实体的主体部分。
使用HEAD可以:
在不获取资源的情况下了解资源的情况;
通过查看响应中的状态码,看看某个对象是否存在;
通过查看首部,测试资源是否被修改了。
HEAD示例:
3.PUT:与GET从服务器读取文档相反,PUT方法会向服务器写入文档。
允许用户对内容进行修改。
PUT示例:
4.POST:起初是用来向服务器输入数据的,实际上通常会用它来支持HTML的表单。表单中填好的数据通常会被送给服务器,然后由服务器将其发送到它要去的地方。
POST示例:
5.TRACE:客户端发起一个请求时,这个请求可能要穿过防火墙、代理、网关或其他一些应用程序。每个中间节点都可能会修改原始的HTTP请求。
TRACE方法允许客户端在最终将请求发送给服务器时,看看它变成了什么样子。
TRACE请求会在目的服务器端发起一个环回诊断,行程最后一站的服务器会弹回一条TRACE响应,并在响应主体中携带它收到的原始请求报文。这样客户端就可以查看在所有中间HTTP应用程序组成的请求/响应链上,原始报文是否以及如何被毁坏或者修改过。
TRACE主要用于诊断。TRACE请求中不能带有实体的主体部分。
TRACE示例:
6.OPTIONS:请求Web服务器告知其支持的各种功能,可以询问服务器通常支持哪些方法,或者对某些特殊资源支持哪些方法。
OPTIONS示例:
7.DELETE:请服务器删除请求URL所指定的资源。客户端应用程序无法保证删除操作一定会被执行,因为HTTP规范允许服务器在不通知客户端的情况下撤销请求。
DELETE示例:
8.扩展方法:扩展方法指的就是没有在HTTP/1.1规范中定义的方法。
世界上几乎所有的HTTP通信都是由TCP/IP承载的,TCP/IP是全球计算机及网络设备都在使用的一种常用的分组交换网络分层协议集。
Web浏览器通过TCP连接与Web服务器进行交互
http://www.joes-hardware.com:80/power-tools.html
1.浏览器解析出主机名
2.浏览器查询这个主机名的IP地址(DNS)
3.浏览器获得端口号(80)
4.浏览器发起到202.43.78.3端口80的连接
5.浏览器向服务器发送一条HTTP GET报文
6.浏览器从服务器读取HTTP响应报文
7.浏览器关闭连接
TCP为HTTP提供了一条可靠的比特传输管道,从TCP连接一端填入的字节会从另一端以原有的顺序,正确地传送出来。
TCP流是分段的,由IP分组传送:
TCP的数据是通过名为IP分组的小数据块来发送的。
HTTP要传送一条报文时,会以流的形式将报文数据的内容通过一条打开的TCP连接按序传输,TCP收到数据流之后,会将数据流砍成被称作段的小数据块,并将段封装在IP分组中,通过因特网进行传输。所有这些工作都是由TCP/IP软件来处理的。
每个IP分组中包括:
一个IP分组首部,一个TCP段首部,一个TCP数据块。
TCP连接是通过4个值来识别的:
<源IP地址,源端口号,目的IP地址,目的端口号>
这四个值一起唯一地定义了一条连接。两条不同的TCP连接不能拥有4个完全相同的地址组件值(不同连接的部分组件可以拥有相同的值)。
TCP客户端和服务器通过TCP套接字接口进行通信流程:
服务器:创建新的套接字,将套接字绑定到端口80上,允许套接字进行连接,等待连接
客户端:获取IP地址和端口号,创建新的套接字,连接到服务器IP:port上
服务器:通知应用程序有连接到来,开始读取请求
客户端:连接成功,发送HTTP请求,等待HTTP响应
服务器:处理HTTP请求报文,回送HTTP响应,关闭连接
客户端:处理HTTP响应,关闭连接
1.HTTP事务的时延
TCP网络时延的大小取决于硬件速度、网络和服务器的负载,请求和响应报文的尺寸,以及客户端和服务器之间的距离。
2.TCP连接的握手时延
3.延迟确认
由于因特网自身无法确保可靠的分组传输,所以TCP实现了自己的确认机制来确保数据的成功传输。
4.TCP慢启动
TCP连接会随着时间进行自我调谐,起初会限制连接的最大速度,如果数据成功传输,会随着时间的推移提高传输的速度,这种调谐被称为TCP慢启动,用于防止因特网的突然过载和拥塞。
TCP慢启动限制了一个TCP端点在任意时刻可以传输的分组数。发送一个分组,等待确认,再发送两个分组,等待确认,可以发送四个分组,以此类推。
5.Nagle算法与TCP_NODELAY
Nagle算法试图在发送一个分组之前,将大量TCP数据绑定在一起,以提高网络效率。
Nagle算法鼓励发送全尺寸的段,只有当所有其他分组都被确认之后,Nagle算法才允许发送非全尺寸的分组,如果其他分组仍然在传输中,就将那部分数据缓存起来,只有当挂起分组被确认,或者缓存中积累了足够发送一个全尺寸分组的数据时,才会将缓存的数据发送出去。小的HTTP报文可能无法填满一个分组,可能会因为等待那些永远不会到来的额外数据而产生时延。
6.TIME_WAIT时延和端口耗尽
TIME_WAIT端口耗尽是很严重的性能问题,会影响到性能基准,但在现实中相对较少出现。
最常见的TCP相关时延:
TCP连接建立握手
TCP慢启动拥塞控制
数据聚集的Nagle算法
用于捎带确认的TCP延迟确认算法
TIME_WAIT时延和端口耗尽
TCP建立连接三次握手:
1.请求新的TCP连接时,客户端要向服务器发送一个小的TCP分组。这个分组中设置了一个特殊的SYN标记,说明这是一个连接请求
2.如果服务器接受了连接,就会对一些连接参数进行计算,并向客户端回送一个TCP分组,这个分组中的SYN和ACK标记都被置位,说明连接请求已被接受。
3.最后,客户端向服务器发送一条确认信息,通知它连接已成功建立。
提高HTTP的连接性能的方法:
并行连接:通过多条TCP连接发起并发的HTTP请求
持久连接:重用TCP连接,以消除连接及关闭时延
管道化连接:通过共享的TCP连接发起并发的HTTP请求
复用的连接:交替传送请求和响应报文。
HTTP允许客户端打开多条连接,并行地执行多个HTTP事务。
并行连接可能会提高页面的加载速度
并行连接不一定更快
并行连接可能让人感觉更快一些
并行连接缺点:
每个事务都会打开/关闭一条新的连接,会耗费时间和带宽
由于TCP慢启动特性的存在,每条新连接的性能都会有所降低
可打开的并行连接数量实际上是有限的
在事务处理结束之后仍然保持在打开状态的TCP连接被称为持久连接。非持久连接会在每个事务结束之后关闭,
持久连接会在不同事务之间保持打开状态,直到客户端或服务器决定将其关闭为止。
持久连接与并行连接配合使用可能是最高效的方式。
在响应到达之前,可以将多条请求放入队列。
所有HTTP客户端、服务器或代理都可以在任意时刻关闭一条TCP传输连接。
常见的HTTP请求首部:
1.From 首部包含了用户的E-mail地址。每个用户都有不同的E-mail地址,所以在理想情况下,可以将这个地址作为可行的源端来识别用户。
2.User-Agent首部可以将用户所用浏览器的相关信息告知服务器,包括程序的名称和版本,通常还包含操作系统的相关信息。
3.Referer首部提供了用户来源页面的URL。
4.Authorization 用户名和密码
5.Client-IP 客户端的IP地址
6.X-Forwarded-for 客户端的IP地址
7.Cookie 服务器产生的ID标签
早期的Web先锋曾尝试着将客户端IP地址作为一种标识形式使用。如果每个用户都有不同的IP地址,IP地址也很少会发生变化,而且Web服务器可以判断出每条请求的客户端IP地址的话,这种方案是可行的。
为了使Web站点的登录更加简便,HTTP中包含了一种内建机制,可以用www-Authorization首部和Authorization首部向Web站点传送用户的相关信息。
一旦登录,浏览器就可以不断地在每条发往这个站点的请求中发送这个登录信息了,这样就总是有登录信息可用了。
有些Web站点会为每个用户生成特定版本的URL来追踪用户的身份,通常会对真正的URL进行扩展,在URL路径开始或结束的地方添加一些状态信息。Web服务器会动态生成一些超链,继续维护URL中的状态信息。
缺点:
丑陋的URL
无法共享URL
破坏缓存
额外的服务器负荷
逃逸口
在会话间是非持久的
示例:
cookie是当前识别用户,实现持久会话的最好方式。
用户首次访问Web站点时,Web服务器对用户一无所知,Web服务器希望这个用户会再次回来,所有想给这个用户拍上一个独有的cookie,这样以后它就可以识别出这个用户了。cookie中包含了一个由名字=值(name=value)这样的信息构成的任意列表。
会话cookie:
会话cookie是一种临时cookie,它记录了用户访问站点时的设置和偏好,用户退出浏览器时,会话cookie就被删除了。
持久cookie:
持久cookie的生存时间更长一些,它们存储在硬盘上,浏览器退出,计算机重启时它们仍然存在,通常会用持久cookie维护某个用户会周期性访问的站点的配置文件或登录名。
会话cookie和持久cookie唯一的区别就是它们的过期时间。
cookie的基本思想就是让浏览器积累一组服务器特有的信息,每次访问服务器时都将这些信息提供给它。
cookies.txt的文本文件,每一行都代表一个cookie
domian(域):cookie的域
allh:是域中所有的主体都获取cookie,还是只有指定了名字的主机获取
path(路径):域中域cookie相关的路径前缀。
secure(安全):是否只有在使用SSL连接时才发送这个cookie
expiration(过期):从格林尼治标准时间1970年1月1日 00:00:00开始的cookie过期秒数
name(名字):cookie变量的名字
value(值):cookie变量的值
产生cookie的服务器可以向Set-Cookie响应首部添加一个Domain属性来控制哪些站点可以看到那个cookie。
示例:Set-cookie:user=“mary17”; domain=“airtravelbargains.com”
访问任意以.airtravelbargains.com结尾的站点,Cookie首部都会被发布出去。
cookie规范甚至允许用户将cookie与部分Web站点关联起来,可以通过Path属性来实现这一功能,在这个属性列出的URL路径前缀下所有cookie都是有效的。
示例:www.airtravelbargains.com可能会将部分Web用户汽车租赁 www.airtravelbargains.com/autos/ 用一个独立的cookie记录用户喜欢的汽车尺寸。
生成cookie:Set-cookie:pref=compact; domian=“airtravelbargains.com”;path=/autos/
如果访问www.airtravelbargains.com/specials.html 只会获得 Cookie:user=“mary17”
如果访问www.airtravelbargains.com/autos/cheapo/index.html 会获得 Cookie:user=“mary17” Cookie:pref=compact
因此cookie就是由服务器贴到客户端上,由客户端维护的状态片段,只会回送给那些合适的站点。
密码:对文本进行编码,使偷窥者无法识别的算法
秘钥:改变密码行为的数字化参数
对称秘钥加密系统:编/解码使用相同秘钥的算法
不对称秘钥加密系统:编/解码使用不同秘钥的算法
公开秘钥加密系统:一种能够使数百万计算机便捷地发送机密报文的系统
数字签名:用来验证报文未被伪造或篡改的校验和,数字签名是附加在报文上的特殊加密校验码。
数字证书:有一个可信的组织验证和签发的识别信息
证书的主要内容:
HTTPS就是在安全的传输层上发送的HTTP。HTTPS没有将未加密的HTTP报文发送给TCP,并通过世界范围内的因特网进行传输,它在将HTTP报文发送给TCP之前,先将其发送给了一个安全层,对其进行加密。
请求一个客户端对某Web资源执行某事务时,它会去检查URL方案
SSL握手过程:
客户端发送可供选择的密码并请求证书
服务器发送选中的密码和证书
客户端发送保密信息,客户端和服务器生成密钥
客户端和服务器互相告知,开始加密过程。
OpenSSL是SSL和TLS最常见的开源实现,
可以从https://www.openssl.org/获得OpenSSL的相关信息。
如果把HTTP报文想象成因特网货运系统中的箱子,那么HTTP实体就是报文中实际的货物。
HTTP实体首部(10个基本字体首部字段)
Content-Type:实体中所承载对象的类型
Content-Length:所传送实体的长度或大小
除非使用了分块编码,否则Content-Length首部就是带有实体主体的报文必须使用的。使用Content-Length首部是为了能够检测出服务器崩溃而导致的报文截尾,并对共享持久连接的多个报文进行正确分段。
Content-Language:与所传送对象最相配的人类语言
Content-Encoding:对象数据所做的任意变换
Content-Location:一个备用位置,请求时可通过它获得对象
Content-Range:如果这是部分实体,这个首部说明它是整体的哪个部分
Content-MD5:实体主体内容的校验和
Last-Modified:所传输内容在服务器上创建或最后修改的日期时间
Expires:实体数据将要失效的日期时间
Allow:该资源所允许的各种请求方法 例如GET和HEAD
ETag:这份文档特定实例的唯一验证码。
Cache-Control:指出应该如何缓存该文档。
HTTP的早期版本采用关闭连接的办法来划定报文的结束,但是没有Content-Length的话,客户端无法区分到底是报文结束时正常的连接关闭,还是报文传输中由于服务器崩溃而导致的连接关闭,客户端需要通过Content-Length来检测报文截尾。
报文截尾的问题对缓存代理服务器来说尤其严重。如果缓存服务器收到被截尾的报文却没有识别出截尾的话,它可能会存储不完整的内容并多次使用它来提供服务,缓存代理服务器通常不会为没有显示Content-Length首部的HTTP主体做缓存,以此来减小缓存已截尾报文的风险。
错误的Content-Length比缺少Content-Length还要糟糕
如果响应通过持久连接传送,就可能有另一条HTTP响应紧随其后,客户端通过Content-Length首部就可以知道报文在何处结束,下一条报文从何处开始。因为连接是持久的,客户端无法依赖连接关闭来判别报文的结束。如果没有Content-Length首部,HTTP应用程序就不知道某个实体主体在哪里结束,下一条报文从哪里开始。
为检测实体主体的数据是否被不经意地修改,发送方可以在生成初始的主体时,生成一个数据的校验和,这样接收方就可以通过检查这个校验和来捕获所有意外的实体修改了。
Content-Type首部字段说明了实体主体的MIME类型。客户端应用程序使用MIME类型来解释和处理其内容。
常用媒体类型
text/html:实体主体是HTML文档
text/plain:实体主体是纯文本文档
image/gif:实体主体是GIF格式的图像
image/jpeg:实体主体是JPEG格式的图像
audio/x-wav:实体主体是包含WAV格式声音数据
model/vrml:实体主体是三维的VRML模型
application/vnd.ms-powerpoint:实体主体是Microsoft PowerPoint演示文档
multipart/byteranges:实体主体有若干部分,每个部分都包含了完整文档中不同的字节范围
message/http:实体主体包含完整的HTTP报文。
Content-Type首部还支持可选的参数来进一步说明内容的类型。 Content-Type:text/html;charset=iso-8859-4
1.网站服务器生成原始响应报文,其中有原始的Content-Type和Content-Length首部。
2.内容编码服务器创建编码后的报文。编码后的报文有同样的Content-Type但Content-Length可能不同。内容编码服务器在编码后的报文中增加Content-Encoding首部,这样接收的应用程序就可以进行解码了。
3.接收程序得到编码后的报文,进行解码,获得原始报文。
HTTP定义了一些标准的内容编码类型,并允许用扩展编码的形式增添更多的编码。
常见的编码代号
gzip:表明实体采用GNU zip编码
compress:表明实体采用Unix的文件压缩程序
deflate:表明实体使用zlib的格式压缩的
identity:表明没有对实体进行编码。当没有Content-Encoding首部时,就默认为这种情况
为了避免服务器客户端不支持的编码方式,客户端就把自己支持的内容编码方式列表放在请求的Accept-Encoding首部里发出去,
如果HTTP请求中没有包含Accept-Encoding首部,服务器就可以假设客户端能够接受任何编码方式。
内容编码可以与传输编码同时使用。
传输编码是为了改变报文中的数据在网络上传输的方式。
经过内容编码的报文,只是对报文的实体部分进行了编码,而对于经过传输编码的报文来说,编码作用在整个报文上,报文自身的结构发生了改变。
在其他一些协议中会用传输编码来保证报文经过网络时能得到可靠传输。在HTTP协议中,可靠传输关注的焦点有所不同,因为底层的传输设施已经标准化并且容错性更好。
只有在少数一些情况下所传输的报文主体可能会引发问题,(1)未知的尺寸(2)安全性
HTTP协议中只定义了两个首部来描述和控制传输编码
Transfer-Encoding:告知接收方为了可靠地传输报文,已经对其进行了何种编码
TE:用在请求首部中,告知服务器可以使用哪些传输编码扩展。
请求使用了TE首部来告诉服务器它可以接受分块编码(如果是HTTP/1.1应用程序的话)并且愿意接受附在分块编码的报文截尾上的拖挂。
TE:trailers,chunked
对它的响应中包含Transfer-Encoding首部,用户告诉接收方已经用分块编码对报文进行了传输编码。
Transfer-Encoding:chunked
传输编码规则:
传输编码集合中必须包括分块,唯一的例外是使用关闭连接来结束报文
当使用分块传输编码时,它必须是最后一个作用到报文主体上的,
分块传输编码不能多次作用到一个报文主体上。
分块编码把报文分割为若干个大小已知的块,块之间是紧挨着发送的,这样就不需要在发送之前知道整个报文的大小了。
分块编码是一种传输编码,因此是报文的属性,而不是主体的属性。
服务器应当告知客户端能够将内容缓存多长时间,在这个时间之内就是新鲜的,服务器可以用这两个首部之一来提供这种消息
Expires(过期)和 Cache-Control(缓存控制)
Cache-Control首部的指令
请求
no-cache,no-store,max-age,max-stale,min-fresh,no-transform,only-if-cached
响应
public,private,no-cache,no-store,no-transform,must-revalidate,proxy-revalidate
max-age,s-max-age
如果服务器上的文档和已过期的缓存副本相同,而缓存服务器还是要从原始服务器上取文档的话,那缓存服务器就是在浪费网络带宽,
给缓存服务器和原始服务器增加不必要的负载,使所有事情都变慢了。为了避免这种情况,HTTP为客户端提供了一种方法,
仅当资源改变时才请求副本,这种特殊请求称为有条件的请求。有条件的请求是标准的HTTP请求报文,但仅当某个特定条件为真时才执行。
HTTP把验证码分为两类:弱验证码和强验证码
弱验证码不一定能唯一标识资源的一个实例,而强验证码必须如此。
服务器通过HTTP协议的Content-Type首部中的charset参数和Content-Language首部告知客户端文档的字母表和语言。
客户端发送Accept-Charset首部和Accept-Language首部,告知服务器它理解哪些字符集编码算法和语言以及其中的优先顺序。
Accept-Language:fr,en;q=0.8
Accept-Charset:iso-8859-1,utf-8
q=0.8 是质量因子。说明英语的优先级(0.8)比法语低,默认值是1.0
字符集不对,字符就不对
如果客户端使用了错误的字符集参数,客户端就会显示一些奇怪的错乱字符。
字符:字符是书写的最基本的构建单元,字符可以表示字符、数字、标点、表意符号、数学符号或其他书写的基本单元。
语言标记是命名口语的标准化字符串短语。
Content-Language首部字段将包含
法语:Content-Language:fr
Accept-Language首部
法语:Accept-Language:fr
子标记:语言标记有一个或多个部分,用连子号分隔,称为子标记
第一个子标记称为主子标记,其值是标准化的
第二个子标记是可选的,遵循它自己的命名标准
其他尾随的子标记都是未注册的。
主子标记中只能含有字母(A-Z)