1. HTTP介绍
- HTTP是
Hyper Text Transfer Protocol
的缩写,即超文本传输协议。它是一种请求/响应式的协议,客户端在与服务器端建立连接后,就可以向服务器端发送请求,这种请求被称作HTTP请求,服务器端接收到请求后会做出响应,称为HTTP响应,客户端与服务器端在HTTP 下的交互过程如图3-1所示。
- 从图3-1中可以清楚地看到客户端与服务端使用HTTP通信的过程,接下来总结一下HTTP协议的特点,具体如下。
(1) 支持客户端(浏览器就是一种 Web客户端)/服务器模式。
(2) 简单快速:客户端向服务器请求服务时,只需传送请求方式和路径。常用的请求方式有GET、POST等,每种方式规定了客户端与服务器联系的类型不同。由于 HTTP简单,使得HTTP服务器的程序规模小,因而通信速度很快。
(3) 灵活:HTTP 允许传输任意类型的数据,正在传输的数据类型由Content-Type
加以标记。
(4) 无状态:HTTP是无状态协议。无状态是指协议对于事务处理没有记忆能力,如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。
2. HTTP 1.0 和 HTTP 1.1
- HTTP自诞生以来,先后经历了很多版本,其中,最早的版本是 HTTP 0.9,它1990年被提出。后来,为了进一步完善HTTP,先后在1996年提出了版本1.0,在1997年提出了版本1.1。由于HTTP 0.9版本已经过时,这里不作过多讲解。接下来,只针对HTTP 1.0和 HTTP 1.1进行详细地讲解。
2.1 HTTP 1.0
- 基于HTTP1.0协议的客户端与服务器在交互过程中需要经过建立连接、发送请求信息、回送响应信息、关闭连接4个步骤,具体交互过程如图3-2所示。
- 从图3-2中可以看出,客户端与服务器建立连接后,每次只能处理一个 HTTP请求。对于内容丰富的网页来说,这样的通信方式明显有缺陷。例如,下面的一段HTML代码:
<html>
<body>
<img src="/image01.jpg">
<img src="/image02.jpg">
<img src="/image03.jpg">
</body>
</html>
- 上面的 HTML文档中包含三个
<img>
标记,由于<img>
标记的src
属性指明的是图片的URL
地址,因此,当客户端访问这些图片时,还需要发送三次请求,并且每次请求都需要与服务器重新建立连接。如此一来,必然导致客户端与服务器端交互耗时,影响网页的访问速度。
2.2 HTTP 1.1
- 为了克服上述HTTP 1.0的缺陷,HTTP1.1版本应运而生,它支持持久连接,也就是说在一个 TCP 连接上可以传送多个 HTTP 请求和响应,从而减少了建立和关闭连接的消耗和延时。基于 HTTP 1.1的客户端和服务器端的交互过程,如图3-3所示。
- 从图3-3中可以看出,当客户端与服务器端建立连接后,客户端可以向服务器端发送多个请求,并且在发送下个请求时,无须等待上次请求的返回结果。但服务器必须按照接受客户端请求的先后顺序依次返回响应结果,以保证客户端能够区分出每次请求的响应内容。由此可见,HTTP 1.1不仅继承了HTTP 1.0的优点,而且有效解决了HTTP 1.0的性能问题,显著地减少了浏览器与服务器交互所需要的时间。
3. HTTP消息
- 当用户在浏览器中访问某个
URL
地址,单击网页的某个超链接或者提交网页上的form
表单时,浏览器都会向服务器发送请求数据,即HTTP请求消息
。服务器接收到请求数据后,会将处理后的数据回送给客户端,即HTTP 响应消息
。HTTP请求消息和HTTP响应消息统称为HTTP消息。 - 在HTTP消息中,除了服务器端的
响应实体内容(HTML 网页、图片等)
以外,其他信息对用户都是不可见的,要想观察这些“隐藏”的信息,需要借助一些网络查看工具,如:F12等。
(1) 在浏览器的地址栏中输入 www.baidu.com
访问百度首页,在F12中可以看到请求的 URL地址,如图所示。
(2) 单击URL地址左边的Name,在展开的默认头信息选项卡中可以看到格式化后的响应头信息和请求头信息。单击请求头信息一栏左边的“原始头信息”,可以看到原始的请求头信息,具体如下所示;
- 在上述请求消息中,第一行为请求行,请求行后面的为请求头消息,空行代表请求头的结束。
(3) 单击响应头信息一栏左边的“原始头信息”,可以看到原始的响应头信息,如下所示:
- 在上面的响应消息中,第一行为响应状态行,响应状态行后面的为响应消息头,空行代表响应消息头的结束。
4. HTTP请求消息
- 在 HTTP中,一个完整的请求消息是由请求行、请求头和实体内容三部分组成,其中,每部分都有各自不同的作用。本节将围绕HTTP请求消息的每个组成部分进行详细的讲解。
4.1 HTTP请求行
- HTTP请求行位于请求消息的第一行,它包括三个部分,分别是请求方式、资源路名以及所使用的HTTP版本,具体示例如下:
GET /index.html HTTP/1.1
- 上面的示例就是一个HTTP请求行,其中,
GET
是请求方式,index.html
是请求源路径,HTTP/1.1
是通信使用的协议版本。需要注意的是,请求行中的每个部分需要用空格分隔,最后要以回车换行结束。 - 关于请求资源和协议版本,读者都比较容易理解,而 HTTP请求方式对读者来说比较陌生,接下来就针对HTTP的请求方式进行具体分析。
- 在 HTTP的请求消息中,请求方式有
GET,POST、 HEAD、OPTIONS、 DELETE,TRACE、PUT和 CONNECT
共8种,每种方式都指明了操作服务器中指定URI
资源的方式,它们表示的含义如表3-1所示。
- 表3-1中列举了HTTP的8种请求方式,其中最常用的就是
GET
和POST
方式,接下来,针对这两种请求方式进行详细讲解,具体如下所示。
1. GET 请求方式
- 当用户在浏览器地址栏中直接输入某个
URL
地址或者单击网页上的一个超链接时,浏览器将使用GET
方式发送请求。如果将网页上的form
表单的method
属性设置为“GET
”或者不设置method
属性(默认值是GET
),当用户提交表单时,浏览器也将使用GET
方式发送请求。 - 如果浏览器请求的
URL
中有参数部分,在浏览器生成的请求消息中,参数部分将附加在请求行中的资源路径后面。先来看一个URL
地址,具体如下,
http://wwrw.xdr630.com/javaForm?username=xdr630&password=123456
- 在上述
URL
中,“?
”后面的内容为参数信息。参数是由参数名和参数值组成的,并且中间使用等号(=
)进行连接。需要注意的是,如果URL地址中有多个参数,参数之间需要用“&
”分隔。 - 当浏览器向服务器发送请求消息时,上述
URL
中的参数部分会附加在要访问的URI
咨源后面.具体加下所示,
GET /javaForm?username=xdr630&password=123456 HTTP/1.1
- 需要注意的是,使用
GET
方式传送的数据量有限,最多不能超过1KB
.
2. POST 请求方式
- 如果网页上
form
表单的method
属性设置为“POST
”,当用户提交表单时,浏览器将使用POST
方式提交表单内容,并把各个表单元素及数据作为HTTP消息的实体内容发送给服务器,而不是作为URI
地址的参数传递。另外,在使用POST
方式向服务器传递数据时,Content-Type
消息头会自动设为“application/x-www-form-urlencoded
”,Content-Length
消息头会自动设置为实体内容的长度,具体示例如下:
POST /javaForm HTTP/1.1
Host: www.xdr630.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 17
username=xdr630&password=123456
- 对于使用
POST
方式传递的请求信息,服务器端程序会采用与获取URI
后面参数相同的方式来获取表单各个字段的数据。 - 需要注意的是,在实际开发中,通常都会使用
POST
方式发送请求,其原因主要有两个,具体如下。
POST
传输数据大小无限制
由于GET
请求方式是通过请求参数传递数据的,因此最多可传递1KB
的数据。而POST
请求方式是通过实体内容传递数据的,因此可以传递数据的大小没有限制POST
比GET
请求方式更安全
由于GET
请求方式的参数信息都会在URL
地址栏明文显示,而POST
请求方式传递的参数隐藏在实体内容中,用户是看不到的,因此,POST
比GET
请求方式更安全。
5. 测试GET请求方式
(1) 创建一个HTML文件,GET.html
,如下所示:
GET.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="get">
用户名:<input type="text" name="username" style=" 150px"><br>
密码: <input type="text" name="password" style=" 150px"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
-
提交后:这时地址栏中的URL地址发生了变化,在原有的URL地址后面附加上了参数信息
-
查看显示的请求头信息,发现在请求行的URL请求资源后附加了参数信息,如图
-
而在Query String Parameters
6. 测试POST请求方式
POST.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" method="post">
用户名:<input type="text" name="username" style=" 150px"><br>
密码: <input type="text" name="password" style=" 150px"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
- 提交后,URL地址栏没有变化。F12查看发现请求的参数被加密了
- F12查看,发现在请求消息中多了两个请求消息头
- 新添加的两个消息头中,
Content-Type
表示实体内容的数据格式,Content-Length
表示实体的内容长度。 - F12 中看到 Form Data 就是提交的表单信息,也就是HTTP请求消息的实体内容,也就是说,在POST请求方式中,表单的内容将作为实体内容提交给服务器。
7. HTTP请求消息头
- 在HTTP请求消息中,请求行之后,便是若干请求消息头。请求消息头主要用于向服务器端传递附加消息,例如,客户端可以接收的数据类型、压缩方法、语言以及发送请求的超链接所属页面的URL地址等信息,具体示例如下:
- 从上面的请求消息头中可以看出,每个请求消息头都是由一个头字段名称和一个值构成,头字段名称和值之间用冒号(
:
)和空格()
分隔,每个请求消息头之后使用一个回车换行符标志结束。需要注意的是,头字段名称不区分大小写,但习惯上将单词的第一个字母大写。 - 当浏览器发送请求给服务器时,根据功能需求的不同,发送的请求消息头也不相同,接下来,针对一些常用的请求头字段进行详细讲解。
1. Accept
- Accept头字段用于指出客户端程序(通常是浏览器)能够处理的
MIME(Multi-purpose Internet Mail Extensions,多用途互联网邮件扩展)
类型。例如如果浏览器和服
务器同时支持png
类型的图片,则浏览器可以发送包含image/png
的Accept头字段,服务器检查到Accept头中包含image/png
这种MIME
类型,可能在网页中的img
元素中使用png
类型的文件。MIME
类型有很多种,例如,下面的这些 MIME类型都可以作为Accept头字段的值。
2. Accept-Charset
- Accept-Charset 头字段用于告知服务器端客户端所使用的字符集,具体示例如下:
Accept-Charset: ISO-8859-1
- 在上面的请求头中,指出客户端服务器使用
ISO-8859-1
字符集。如果想指定多种字符集,则可以在Accept-Charset
头字段中将指定的多个字符集以逗号分隔,具体示例如下:
Accept-Charset: ISO-8859-1,unicode-1-1
- 需要注意的是,如果
Accept-Charset
头字段没有在请求头中出现,则说明客户端能接受使用任何字符集的数据。 - 如果Accept-Charset头出现在请求消息里,但是服务器不能发送采用客户端期望字符集编码的文档,那么服务器将发送一个
406
错误状态响应,406
是一个响应状态码,表示服务器返回内容使用的字符集与Accept-Charset
头字段指定的值不兼容,关于状态码的相关知识,将在后面的章节进行详细讲解。
3. Accept-Encoding
- Accept-Encoding头字段用于指定客户端能够进行解码的数据编码方式,这里的编码方式通常指的是某种压缩方式。在 Accept-Encoding头字段中,可以指定多个数据编码方式,它们之间以逗号分隔,具体示例如下:
Accept-Encoding: gzip,compress
- 在上面的头字段中,
gzip
和compress
这两种格式是最常见的数据编码方式。在传输较大的实体内容之前,对其进行压缩编码,可以节省网络带宽和传输时间。服务器接收到这个请求头,它使用其中指定的一种格式对原始文档内容进行压缩编码,然后再将其作为响应消息的实体内容发送给客户端,并且在Content-Encoding
响应头中指出实体内容所使用的压缩编码格式。浏览器在接收到这样的实体内容之后,需要对其进行反向解压缩。 - 需要注意的是,
Accept-Encoding
和Accept
消息头不同,Accept
请求头指定的MIME
类型是指解压后的实体内容类型,Accept-Encoding
消息头指定的是实体内容压缩的方式。
4. Accept-Language
- Accept-Language头字段用于指定客户端期望服务器返回哪个国家语言的文档,它的值可以指定多个国家的语言,语言之间用逗号分隔,具体示例如下:
Accept-Language: zh-CN,en-us
- 在上述示例中,
zh-cn
代表中文(中国),en-us
代表英语(美国),这些值不需要记忆。 - 需要注意的是,浏览器会根据“语言首选项”对话框中语言列表的先后顺序,生成相应的Accept-Language消息头。
- 服务器只要检查Accept-Language请求头中的信息,按照其中设置的国家语言的先后顺序,首先选择返回位于前面的国家语言的网页文档,如果不能返回,则依次返回后面的国家语言的网页文档。
5. Authorization(授权)与Proxy-Authorization
- 当客户端访问受口令保护的网页时, Web服务器会发送401响应状态码和
WWW-Authenticate
响应头,要求客户端使用Authorization
请求头来应答。根据WWW-Authenticate
响应头指定的认证方式不同,Authorization
请求头中的内容格式也不一样。WWW-Authenticate
响应头指定的认证方式有两种:BASIC
和DIGEST
。对于BASIC
认证方式,客户端需要把用户名和密码用“:”分隔,然后经过Base64
编码之后传送给Web服务器。 - 例如,将用户名为
Ann
、密码为666888
的用户信息“Ann:666888
”进行Base64
编码,形成的Authorization
请求头字段内容如下所示:
Authorization: Basic Qw5uOjY2Njg4OA==
- 然而,使用
Base64
编码的数据很容易被解码,这实际上相当于是一种未加密的明文传送方式,装备了网络监视工具的计算机截获到该信息后,很容易破解出用户名和密码。 - 如果使用
DIGEST
认证方式,服务器首先向浏览器发送一些用于验证过程的信息及附加信息,浏览器将这些信息与用户名和密码以及某些其他信息进行混合后,再执行MD5
加密算法,将得到的结果和附加信息一起以明文文本通过网络发送给服务器。服务器也使用与客户端一样的信息和附加信息,将它们和所保存的客户端密码执行散列算法,然后将计算结果和客户端的结果进行比较,只有这两个数字完全相同才允许访问。 Proxy-Authorization
头字段的作用和用法与Authorization
头字段基本相同,只不过Proxy-Authorization
请求头是服务器端向代理服务器发送的验证信息。
6. Host
- Host头字段用于指定资源所在的主机名和端口号,格式与资源的完整URL中的主机名和端口号部分相同,具体示例如下所示:
Host: www.xdr630.top
- 在上述示例中,由于浏览器连接服务器时默认使用的端口号为80,所以“www.xdr630.top”后面的端口号信息“:80”可以省略。
- 需要注意的是,在HTTP 1.1中,浏览器和其他客户端发送的每个请求包含Host请求头子段,以便访问Web站点时,会根据地址栏中的URL地端所要访问的虚拟Web站点。当浏览器访问Web站点时,会根据地址栏中的URL地址自动生成相应的Host请求头。
7. If-Match
- 浏览器和代理服务器都可以缓存服务器回送的网页文档。当用户再次访问已缓存的页面时,只有网页内容已被更新,服务器才需要把该页面的内容重新回送到客户端,否则会通知浏览器访问本地缓存的页面,以减少不必要的网络传输流量。当服务器为客户端传送网页文件的内容时,可以传输一些代表实体内容特征的头字段,这些头字段被称为实体标签。当客户机再次向服务器请求这个网页文件时,可以使用If-Match头字段附带以前缓存的实体标签内容,这个请求被视为一个条件请求,例如:
If-Match: "repository"
- 其中,"
repository
"是客户端上次访问Web服务器中的该页面时,服务器使用ETag实体标签传送的内容,具体示例如下所示:
ETag: "repository"
- 服务器收到客户端的请求后,会检索If-Match头中的实体标签内容,并与服务器端的代表当前网页内容特征的实体标签内容进行比较。如果两者相同,则表示网页内容没有更改,Web服务器不返回网页文档,让客户端仍然使用以前缓存的网页文档。否则,服务器返回新的网页文件和新的实体标签内容头字段。
8. If-Modified-Since
- If-Modified-Since请求头的作用和 If-Mach类似,只不过它的值为GMT格式的时间。If-Modified-Since请求头被视作一个请求条件,只有服务器中文档的修改时间比IF-Modified-Since请求头指定的时间新,服务器才会返回文档内容。否则,服务器将返回一个304(Not Modified)状态码来表示浏览器缓存的文档是最新的,而不向浏览器返回文档内容,这时,浏览器仍然使用以前缓存的文档。通过这种方式,可以在一定程度上减少浏览器与服务器之间的通信数据量,从而提高了通信效率。
9. Range和If-Range
- Range头字段用于指定服务器只需返回文档中的部分内容及内容范围,这对较大文档的断点续传非常有用。如果客户端在一次请求中只接收到服务器返回的部分内容就中断了,可以在第二次请求中,使用 Range头字段要求服务器只返回中断位置以后的内容。Range头有以下几种使用格式。
(1)Range: bytes=1000-2000
(2) Range: bytes=1000-
(3) Range:bytes=-1000 - 在上面列举的三种格式中,第一种格式请求服务器返回文档中的第1000~2000个字节之间的内容,包括第1000个和第2000个字节的内容。第二种格式请求服务器返回文档中的第1000个字节以后的所有内容。第三种格式请求服务器返回文档中的最后1000个字节的内容。
- If-Range头字段只能伴随着Range头字段一起使用,其设置值可以是实体标签或GMT格式的时间。如果设置值为实体标签,且该标签内容与服务器端代表当前网页内容特征的实体标签内容相同,则服务器按Range头的要求返回网页中的部分内容,否则,服务器返回当前网页的所有内容。如果设置值为GMT格式的时间,并且自从这个时间以来,服务器上保存的该网页文件没有发生修改,服务器会按Range头的要求返回网页中的部分内容,否则,服务器返回当前网页的所有内容。
10. Max-Forward
- Max-Forward头字段指定当前请求可以途经的代理服务器数量,每经过一个代理服务器,此数值就减1。当Max-Forward请求头的值为0时,如果请求还没有到达最终的Web服务器,那么代理服务器将终止转发这个请求,由它来完成对客户机的最终响应。
11. Referer
- 浏览器向服务器发出的请求,可能是直接在浏览器中输入 URL地址而发出,也可能是单击一个网页上的超链接而发出。对于第一种直接在浏览器地址栏中输入 URL地址的情况,浏览器不会发送 Referer请求头,而对于第二种情况,浏览器会使用Referer头字段标识发出请求的超链接所在网页的URL。例如,本地Tomcat服务器的 chapter03项目中有一个 HTML文件 GET.html,GET.html中包含一个指向远程服务器的超链接,当单击这个超链接向服务器发送GET请求时,浏览器会在发送的请求消息中包含Referer头空段.如下所示.
Referer: http://localhost:8080/Test01/GET.html
- Referer头字段非常有用,常被网站管理人员用来追踪网站的访问者是如何导航进入网站的。同时,Referer头字段还可以用于网站的防盗链。有R提太机,版什么是盗链呢?假设一个网站的首页中想显示一些图片信息,而在该网站的服务器中并没有这些图片资源,它通过在 HTML 文件中使用img标记链接到其他网站的图片资源,将其展示给浏览者,这就是盗链。盗链的网站提高了自己网站的访问量,却加重了被链接网站服务器的负担,损害了其合法利益。所以,一个网站为了保护自己的资源,可以通过Referer头检测出从哪里链接到当前的网页或资源,一旦检测到不是通过本站的链接进行的访问,可以进行阻止访问或者跳转到指定的页面。
12. User-Agent
- User-Agent中文名为用户代理;简称
UA
,它用于指定浏览器或者其他客户端程序使用的操作系统及版本、浏览器及版本、浏览器渲染引擎、浏览器语言等,以便服务器针对不同类型的浏览器而返回不同的内容。例如,服务器可以通过检查User-Agent
头,如果发现客户端是一个无线手持终端,就返回一个WML文档;如果客户端是一个普通的浏览器,则返回通常HTML文档。例如,IE浏览器生成的User-Agent请求信息如下:
User-Agent: Mozilla/4.0(compatible;MSIE 8.0; Windows NT 5.1: Trident/4.0)
- 在上面的请求头中,User-Agent头字段首先列出了Mozilla版本,然后列出了浏览器的版本(MSIE 8.0表示 Microsoft IE 8.0)、操作系统的版本(Windows NT 5.1表示Windows XP)以及浏览器的引擎名称(Trident/4.0)。
8. HTTP 响应消息
- 当服务器收到浏览器的请求后,会回送响应消息给客户端。一个完整的响应消息主要包括响应状态行、响应消息头和实体内容,其中,每个组成部分都代表了不同的含义,本节将围绕HTTP响应消息的每个组成部分进行详细的讲解。
1. HTTP响应状态行
- HTTP响应状态行位于响应消息的第一行,它包括三个部分,分别是 HTTP版本一个表示成功或错误的整数代码(状态码)和对状态码进行描述的文本信息,具体示例如下:
HTTP/1.1 200 OK
- 上面的示例就是一个 HTTP 响应消息的状态行,其中 HTTP 1.1是通信使用的协议版本(200是状态码),OK是状态描述,说明客户端请求成功。需要注意的是,请求行中的每个部分需要用空格分隔,最后要以回车换行结束。
- 状态代码由三位数字组成,表示请求是否被理解或被满足。HTTP响应状态码的第一个数字定义了响应的类别,后面两位没有具体的分类,第一个数字有5种可能的取值,具体介绍如下所示。
1xx
:表示请求已接收,需要继续处理。监哗斯分认工源店,价出战条细出网此额海2xx
:表示请求已成功被服务器接收、理解并接受。3xx
:为完成请求,客户端需进一步细化请求。4xx
:客户端的请求有错误。5xx
:服务器端出现错误。
- 下面通过表3-2~表3-6对 HTTP 1.1协议版本下的5种类别的状态码、状态信息(每个状态码后面小括号中的内容就是状态信息)及其作用分别进行说明。
- 表3-2~表3-6列举了HTTP的大多数状态码,这些状态码无须记忆。接下来列举几个Web开发中比较常见的状态码,具体如下。
(1)200
:表示服务器成功处理了客户端的请求。
(2)302
:表示请求的资源临时从不同的URI响应请求,但请求者应继续使用原有位置来进行以后的请求。例如,在请求重定向中,临时 URI应该是响应的Location头字段所指向的资源。
(3)404
;表示服务器找不到请求的资源。例如,访问服务器不存在的网页经常返回此状态码。
(4)500
:表示服务器发生错误,无法处理客户端的请求。
2. HTTP 响应消息头
- 在HTTP响应消息中,第一行为响应状态行,紧接着的是若干响应消息头,服务器端通过响应消息头向客户端传递附加信息,包括服务程序名、被请求资源需要的认证方式,客户端请求资源的最后修改时间、重定向地址等信息。HTTP响应消息头的具体示例如下所示:
- 从上面的响应消息头可以看出,它们的格式和 HTTP请求消息头的格式相同。当服务器向客户端回送响应消息时,根据情况的不同,发送的响应消息头也不相同。接下来,针对―些常用的响应消息头字段进行详细讲解。
1. Accept-Range
- Accept-Range头字段用于说明服务器是否接收客户端使用
Range
请求头字段请求资源。如果服务器想告诉客户机不要使用Range头字段,则使用下面的头信息
Accept-Range: none
- 如果服务器想告诉客户端可以使用以
bytes
为单位的Range请求,则应该使用下面的头信息:
2. Age
- Age头字段用于指出当前网页文档可以在客户端或代理服务器中缓存的有效时间,设置值为一个以秒为单位的时间数,具体示例如下所示:
Age: 1234567
- 客户端再次访问已缓存的某个网页文档内容时,先用当前的时间值减去服务器返回该网页时所设置的Date头字段值,如果结果值小于服务器上返回该网页时所设置的Age头字段的时间值,客户端直接使用缓存中的网页内容。否则,客户端将向服务器发出针对该页面的网页请求。
3. Etag
- Etag头字段用于向客户端传送代表实体内容特征的标记信息,这些标记信息称为实体标签,每个版本的资源的实体标签是不同的,通过实体标签可以判断在不同时间获得的同一资源路径下的实体内容是否相同。例如,在一个文档最后添加一个回车换行,Etag头字段的值就能标识出不同。Etag头字段的格式如下所示:
Etag: abc1234
4. Location
- Location头字段用于通知客户端获取请求文档的新地址,其值为一个使用绝对路径的URL地址,如下所示;
Location: http://www.xdr630.top
- Location头字段和大多数
3xx
状态码配合使用,以便通知客户端自动重新连接到新的地址请求文档。由于当前响应并没有直接返回内容给客户端,所以使用 Location头的HTTP消息不应该有实体内容,由此可见,在HTTP消息头中不能同时出现Location
和Content-Type
这两个头空段
5. Retry-After
- Retry-After头字段可以与503状态码配合使用,告诉客户端在什么时间可以重新发送请求。也可以与任何一个3xx状态码配合使用,告诉客户端处理重定向的最小延时时间。Retry-After头字段的值可以是GMT格式的时间,也可是一个以秒为单位的时间数,具体示例如下:
Retry-After: Sun, 21 Mar 2021 10:00:00
GMTRetry-After: 120 //120秒
6. Server
- Server头字段用于指定服务器软件产品的名称,具体示例如下:
Server: Apache- Coyote/1.1
7. Vary
- Vary用于指定影响了服务器所生成的响应内容的那些请求头字段名,具体示例如下:
Vary: Accept-Language
- 上面的响应头字段说明了服务器响应的内容受到了客户端发送的Accept-Language请求头的影响,服务器根据Accept-Language请求头的值,返回相应语言种类的网页内容。当客户端再次访问已经缓存的资源时,需要检查Vary头字段中指定的请求头字段,检查请求头字段的这次设置与上次的设置是否相同,以此作为是否使用缓存的条件。-例如,上次的请求中Accept-Language头字段的值为en-us,而这次的 Accept-Language头字段的值为zh-cn,即使客户端使用请求资源路径的本地缓存的其他条件都成立,但客户端也不能使用缓存,它仍需向服务器发出访问请求。
8. WWW-Authenticate和Proxy-Authenticate
- 当客户端访问受口令保护的网页文件时,服务器会在响应消息中回送401(Unauthrized)响应状态码和WWW-Authoricate响应头,指示客户端应该在Author-ization请求头中使用WWW-Authoricate响应头指定的认证方式提供用户名和密码信息。WWW-Authenticate响应头中可以指定两种认证方式:
BASIC
和DIGEST
。如果要求客户端采用 BASIC方式传送认证信息,语法格式如下:
WWW-Authenticate: BASIC realm= "xdr630"
- 其中, realm属性用于指定当前资源所属的域,域定义了同一个主机内的一个受保护区间(一组需要保护的资源),它可以是任意字符串。同一台主机上可以有多个域,相同的域内所有的资源都共享相同的账户。如果某个账户具有访问某个资源的权限,那么该账户就能访问同一个域中的其他资源。根据HTTP验证的规范,与某一资源具有相同的目录路径或位于其目录路径的子目录中的资源,与该资源使用相同的域。
- DIGEST认证方式细节比较复杂,想对其进行深入研究的读者可以参阅 RFC2617文档。
- Proxy-Authenticate头字段是针对代理服务器的用户信息验证,其他的作用与用法与 WWW-Authenticate头字段类似。
9. Refresh
- Refresh头字段用于告诉浏览器自动刷新页面的时间,它的值是一个以秒为单位的时间数,具体示例如下所示:
Refresh:3
- 上面所示的Refresh头字段用于告诉浏览器在3秒后自动刷新此页面。
- 需要注意的是,在 Refresh头字段的时间值后面还可以增加一个URL参数,时间值与URL之间用分号(﹔)分隔,用于告诉浏览器在指定的时间值后跳转到其他网页,例如告诉浏览器经过3秒跳转到www.xdr630.top网站,具体示例如下:
Refresh:3; url=http://www.xdr630.top
10. Content-Disposition
- 如果服务器希望浏览器不是直接处理响应的实体内容,而是让用户选择将响应的实体内容保存到一个文件中,这需要使用Content-Disposition头字段。Content-Disposition头字段没有在 HTTP的标准规范中定义,它是从 RFC 2183中借鉴过来的。在RFC 2183中,Content-Disposition指定了接收程序处理数据内容的方式,有inline和attachment两种标准方式, inline表示直接处理,而attachment则要求用户干预并控制接收程序处理数据内容的方式。而在 HTTP应用中,只有attachment是 Content-Disposition的标准方式。attachment后面还可以指定filename参数。filename参数值是服务器建议浏览器保存实体内容的文件名称,浏览器应该忽略filename参数值中的目录部分,只取参数中的最后部分作为文件名。在设置Content-Disposition之前,一定要设置Content-Type头字段,具体示例如下.
Content-Type: application/octet-stream
Content- Disposition: attachment; filename=lee.zip
3. HTTP其他头字段
1. 通用头字段
- 在 HTTP消息中,有些头字段既适用于请求消息也适用于响应消息,这样的字段被称为通用头字段。通用头字段有如下几种:Cache-Control、 Connection、Date, Pragma,Trailer、 Transfer-Encoding,Upgrade、 Via, Warning,关于这些通用头字段的相关讲解具体如下。
1. Cache-Control
- 如果Cache-Control用在请求消息中,它用于通知位于客户端和服务器端之间的理服务器如何使用已缓存的页面。在这种情况下,Cache-Control的值可以是:no-cache、no-store、max-age , max-stale、 min-fresh 、no-transform,only-if-cached等。
- 如果Cache-Control用在响应消息中,它用于通知客户端和代理服务器如何缓存页面,在这种情况下,Cache-Control 的取值可以为public、 private , no-cache、no-store、no-transform,must-revalidate、proxy-revalidate 、 max-age,s-max-age等。
- 在一个Cache-Control头字段中可以设置多个值,它们之间用过号分隔,具体示例如下:
Cache-Control: no- stroe,no-cache,must-revalidage
- 在上面的Cache-Control头字段中,设置的每个值都有特定的含义,接下来,通过表3-7对Cache-Control头字段的一些常用值进行介绍说明。
2. Connection
- Connection头字段用于指定处理完本次请求/响应后,客户端和服务器端是否还要继续保持连接。Connection头字段可以指定两个值,如下所示:罐必监中来都鼓
Connection: Keep-Alive
Connection: close
- 当Connection头字段的值为Keep-Alive时,客户端与服务器在完成本次交互后继续保持连接,当Connection头字段的值为close 时,客户端与服务器在完成本次交互后关闭连接。对于HTTP1.1版本来说,默认采用持久连接,也就是说默认情况下,Connection头字段的值为Keep- Alive.
3. Data
- Date头字段用于表示 HTTP消息产生的当前时间,它的值为GMT格式,具体示例如下:
Mon, 22 Feb 2021 08:29:02 GMT
- 一般情况下,服务器返回的所有响应中必须包括一个 Date头字段.除了下而这此情况。
- 响应状态代码表示服务器的错误,如500(内部服务器错误)或503(服务不可用),那么服务器就不可能产生一个有效的日期。
- 服务器没有时钟,不能提供当前时间,响应就不能设置Date头,这种情况下,服务器也不能设置如 Expire、Last-Modified等这样的头字段。
4. Pragma
- Pragma头字段主要在HTTP 1.0中通知代理服务器和客户端如何使用缓存页面,它的值只能固定设置为no-cache,如下所示:
Pragma: no-cache
- 当Pragma头字段用于响应消息时,指示客户端不要缓存文档;当用于请求消息时,指示代理服务器必须返回一个最新的文档,而不能返回缓存的文档。在HTTP 1.0中,一些浏览器对Pragma头字段的支持不是非常可靠,因此,人们常常通过设置Expires头字段的值为0来实现同样功能。
- 而在 HTTP 1.1中,
Cache-Control
头字段也基本替代了Pragma
头字段的使用。
5. Transfer-Encoding
- 对于HTTP 1.0协议,服务器端和客户端不是持久化连接,当服务器端关闭了TCP连接,客户端就知道响应的数据已经发送完毕。而对于HTTP 1.1来说,由于服务器端和客户端保持持久连接,服务器端必须在响应消息中通过Content-Length头字段通知客户端响应数据的长度,客户端才能知道数据何时传输完毕。然而,在服务器端,有些数据是动态生成的,服务器必须等到所有的内容都生成后才能准确地计算出响应数据的长度,也就是说只有当所有数据生成完毕后服务器端才能响应客户端的请求,这样势必会影响效率。为了解决这个问题,Transfer-Encoding头字段被引人,这个头字段指定响应消息的实体内容采用哪种传输编码方式,目前标准设置值只有chunked,具体示例如下:
Transfer-Encoding: chunked
- 当响应消息中设置了Transfer-Encoding头字段后,会把响应消息的整个实体内容分成一连串分段后再进行传输。每个分段的开始都是一个十六进制的数字,用来表示整个分段的大小。最后一个分段必须是0,用于表示整个 chunked编码数据的结束,如下所示:
HTTP/1.1 200 OK
Content-Type: text/htm1Transfer-Encoding: chunked
7f
<html>
<head>
<title>trailer Example</title>
</head>
<body>
<p> Please wait while we complete your transaction ...</p>
2c
<p>Transaction complete!</p>
</body>
</html>
0
- 上面的响应消息中,7f和2c代表两个分段内容的大小标识信息,所以这种情况下不必用 Content-Length头字段来指定整个实体内容的大小。
6. Trailer
- 一些头字段可以放置在整个 HTTP消息的尾部,也就是可以在实体内容部分之后放置头字段信息。对于放置在尾部的头字段,需要在消息头中使用Trailer字段说明,具体示例如下,
Trailer:Date
- 需要注意的是,Trailer头字段必须在 chunked传输编码的方式下使用。
7. Upgrade
- Upgrade头字段用在客户端,用于指定客户端想要从当前协议切换的新的通信协议。如果服务器端认为切换的协议合适,会在响应消息中设置Upgrade头字段指定切换的协议,Upgrade响应头字段需要和101状态码配合使用,具体示例如下:
//请求消息
GET /HTTP/1.1
Host: 127.0.0.1
Upgrade: TLS/1.0
//响应消息
HTTP/1.1 101 Switching Protocols
Upgrade: TLS/1.0
8. Via
- Via头字段用于指定HTTP 消息所途经的代理服务器所使用的协议和主机名称,这个头字段由代理服务器产生,每个代理服务器必须把它的信息追加到Via字段的最后,以反映 HTTP消息途经的多个代理服务器的顺序,具体示例如下:
Via: HTTP/1.1 Proxy1,HTTP/1.1 Proxy2
- 如果代理服务器所使用的协议为HTTP,Via头字段中的协议名称可以省略,如下所示:
Via: 1.1 Proxy1,1.1 Proxy2
9. Warning
- Warning头字段主要用于说明其他头字段和状态码不能说明的一些附加警告信息,例如提示代理服务器断开网络,如下所示:
warning:112 Disconnected operation
2. 实体头字段
- 请求消息和响应消息中都可以传递实体信息,实体信息包括实体头字段和实体内容,实体头字段是实体内容的元信息,描述了实体内容的属性,例如实体内容的类型、长度、压缩方法、最后的修改时间、数据的有效期等。接下来,本节将针对实体头字段进行详细的讲解。
1. Allow
- Allow头字段指定了请求资源所支持的请求方式(如 GET,POST等),用于通知客户端应该严格按照指定的方式请求资源,如下所示:
Al1ow: GET,HEAD,PUT
- 需要注意的是,Allow头字段必须和405响应状态码一起使用。
2. Content-Language
- Content-Language用于指定返回网页文档的国家语言类型,其设置值是zh-cn,en-us,ja等国家语言的标准名称。由于同一个字符在不同的国家语言中的样式和意义上能有略微区别,如果一些客户端软件正好要对字符文本按不同的国家语言进行不同处理时, Content-Language头字段就比较重要了。Content-Language的具体示例如下所示:
Content-Language: en-us
3. Content-Length
- Content-Length头字段用于表示实体内容的长度(字节数),首先来看一个带有Content-Length头字段的简单的响应消息,具体如下所示:
HTTP/1.1 200 OK
Date: Mon, 22 Feb 2021 09:29:57 GMT
Content- Length:109
<html>
<head>
<title> content-Length Example</title>
</head>
<body>
Content-Length:109
</body>
</html>
- 在上面的响应消息中,从
<html>
中的第一个字符“<”到</hml>
中的最后一个字符“>”,内容的长度为109。 - 在 HTTP 1.1中,浏览器与服务器之间保持持久连接,服务器允许客户端在一个TCP连接上发送多个请求,服务器必须在每个响应中发送一个 Content-Length响应头来标识各个实体内容的长度,以便客户端能分清每个响应内容的结束位置,而不会将上一个响应和下一个响应混淆。
- 如果响应消息中包含 Transfer-Encoding响应头,也就是说响应内容以chunked编码方式返回,那么,Content-Length响应头就不应该设置了。
4. Content-Location
- Content-Location头字段用于指定响应消息中实体内容的实际位置路径(不能简单地认为响应消息中的实体内容所在的路径就是请求资源的路径),当一个请求资源路径对应有多种实体内容形式时,例如,同一请求资源可能有多个国家语言的版本,每个国家语言的版本都有自己的位置,在这种情况下,请求资源路径与响应的实体内容所在的路径可能是不同的,具体示例如下:
//请求消息
GET /docs/index.html HTTP/1.1
Host: httpd.apache.org
Accept- Language: en-us
//响应消息
HTTP/1.1 200 OK
Date: Mon, 22 Feb 2021 09:29:57 GMT
Server: Apache(UNIX)
Content-Location: index_en_us.html
Content-Type: text/html
Content-Language: en-us
- 在上面的示例中,请求消息中需要请求index. html文档,而且要求是英文文档,服务器中发现有可用的英文文档index_en_us.html,就会在响应消息中将Content-Location消息头的值设置为index_en_us. html文档的路径,并把该文档回送给客户端。
- Content-Location的设置值可以是绝对路径,也可以是相对路径,如果是相对路径,则是相对请求资源路径而言的,对于上面的响应消息来说, index, html和 index_en_us.html在同一目录下。
5. Content-Range
- Content-Range头字段用于指定服务器返回的部分实体内容的位置信息。只有客户机使用了Range请求头要求服务器返回实体的部分内容时,服务器的响应头中才会包含Content-Range头,具体示例如下所示:
HTTP/1.1 206 Partial content
Date: wed,15 Nov 1995 06:25:24 GMT
Last-Modified: Wed, 15 Nov 1995 04:58:08 GMT
Content-Range: bytes 21010-47021/47022
Content- Length:26012
Content-Type: image/gif
- 在Content-Range头字段中, bytes说明后面的数据以byte为单位,21010~47021说明返回的内容从第21010个字节开始到第47021个字节结束,47022说明整个实体内容的大小为47022个字节,从 Content-Length头字段可以看出返回的实体内容的长度为26012(47 021-21 010+1)个字节。
6. Content-MD5
- Content-MD5头字段用于提供对实体内容的完整性检查,它的值是对实体内容MD5 数字摘要后再进行 Base64编码的结果。
- MD5 数字摘要算法是一种散列算法,能够通过对一段信息进行运算,产生一个16个字节的数字摘要。如果对输人信息做了任何形式的改变,对改变后的信息再次进行MD5运算所产生的数字摘要和改变之前的数字摘要都不相同。由于通过MD5算法计算的16个字节摘要信息可能无法转化成可打印的 ASCII字符显示,因此需要对这16个字节进行 Base64编码,将其转换为可打印的 ASCII字符。Content-MD5的头字段如下所示:
Content-MD5: ZTFmZDA5MDYyYTMzZGQzMDMxMmixMjc4YThhNTMyM21=
7. Content-Type
- Content-Type用于指出实体内容的MIME类型。MIME(Multipurpose InternetMail Extensions,多用途互联网邮件扩展类型)是一个互联网标准,它设计之初是为了在发送电子邮件时附加多媒体数据,让邮件客户程序能根据其类型进行处理。由于通过HTTP传输的数据也有各种类型,因此,HTTP 也采用了MIME来标识不同的数据类型。客户端通过检查响应头字段 Content-Type中的 MIME类型,就能知道接收到的实体内容代表哪种格式的数据类型,从而进行正确的处理。
- 大多数服务器会在配置文件中设置文件扩展名与MIME类型的映射关系,从而可以根据请求资源的扩展名自动确定 Content-Type的 MIME类型。在Tomcat的 web.xml文件中有大量的
元素,来实现文件扩展名和 MIME类型的映射,下面是web. xml文件的片段:
...
<mime-mapping>
<extension>pdf</extension>
<mime-type>application/pdf</mime-type>
</mime-mapping>
...
- 其中
<mime-mapping >
元素的<extension>
子元素用于指定文件的扩展名,<mime-type>
子元素用于指定该文件扩展名映射的 MIME类型。 - MIME类型包含主类型和子类型,两者之间用“/”分隔,上面的文件片段中的 MIM类型“application/pdf”, application为主类型,pdf为子类型。MIME类型也可以使用“
*
”号通配符,“*/ *
”代表所有的MIME类型,"image/ *
”代表所有image的子类型如果子类型以“x-
”开头,则表示该类型目前还处于实验性的阶段。Content-Type头字段中的 MIME类型后面还可以指定响应内容所使用的字符码表,两者之间用分号(;)和空格隔开,如 Content-Type: text/html; charset=GB2312。如果Content-Type头字段中没有指定字符码表,默认使用的是ISO-8859-1字符码表。