一、HTTP简介
- HTTP简介
HTPP协议
HTTP是HyperText Transfer Protocol(超文本传输协议),它是TCP/IP协议集中的一个应用层协议,
用于定义浏览器与Web服务器之间交换数据的过程以及数据本身的格式。 - HTTP1.0的会话方式
基于HTTP1.0协议的客户机与服务器的信息交换过程
基于HTTP1.0协议的客户机与服务器的信息交换过程包括四个步骤:
建立连接;发送请求消息;回送响应消息;关闭连接。
浏览器与Web服务器的连接过程是短暂的
浏览器与Web服务器的连接过程是短暂的,从浏览器发出请求到Web服务器返回结果后即告终结。
浏览器与Web服务器的连接过程的持续时间与浏览器窗口保持打开的时间无关,
它不是持续到浏览器程序关闭。
HTTP协议是无状态的
HTTP协议是无状态的,上一次请求的响应结果并不会影响下一次请求的响应过程,不管在什么样的情况下,
只要浏览器发出的请求信息完全一样,Web服务器的处理过程也就完全一样。 - HTTP1.1与HTTP1.0的比较
HTTP1.1支持持久连接
在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟。
一个包含许多图像的网页文件的多个请求和应答可以在一个连接中传输,
但每个单独的网页文件的请求和应答仍然需要使用各自的连接。
管道线
HTTP1.1还允许客户端不用等待上一次请求结果返回,就可以发出下一次请求,但服务器端必须按照
接收到客户端请求的先后顺序依次回送响应结果,以保证客户端能够区分出每次请求的响应内容,
这样也显著地减少了整个下载过程所需要的时间。这个功能称之为Pipeline(管道线)。
HTTP1.1还通过增加更多的请求头和响应头来改进和扩充HTTP1.0的功能
增加了Host请求头字段后,浏览器可以使用主机名来明确表示要访问服务器上的哪个Web站点,
这才实现了在一台Web服务器上可以在同一个IP地址和端口号上
使用不同的主机名来创建多个虚拟Web站点。
增加了Connection请求头,当值为Keep-Alive时,客户端通知服务器返回本次请求结果后保持连接;
Connection请求头的值为close时,客户端通知服务器返回本次请求结果后关闭连接。
HTTP1.1还提供了与身份认证、状态管理和Cache缓存等机制相关的请求头和响应头。 - HTTP消息的格式
HTTP消息
浏览器发出的请求信息和Web服务器回送的响应信息都叫HTTP消息。
请求消息
一个完整的请求消息包括:一个请求行、若干消息头,以及实体内容,
其中的一些消息头和实体内容都是可选的,消息头和实体内容之间要用空行隔开。
GET /books/java.html HTTP/1.1
Accept: */*
Accept-Language: en-us
Connection: Keep-Alive
Host: localhost
Referer: http://localhost/links.asp
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
Accept-Encoding: gzip, deflate
空行
上面的请求消息中的第一行为请求行,请求行后面的内容都属于消息头部分。虽然该消息中没有实体内容,
但紧接着消息头部分之后的一个空行(只有回车和换行符的行)必不可少,
这个空行用于标识消息头部分已经结束。
使用GET方式发送不包含实体内容的请求消息;
只有使用POST、PUT和DELETE方式的请求消息中才可以包含实体内容。
响应消息
一个完整的响应消息包括一个状态行、若干消息头,以及实体内容。
响应消息中的一些消息头和实体内容也都是可选的,消息头和实体内容之间也要用空行隔开。
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Thu, 13 Jul 2000 05:46:54 GMT
Content-Length: 2291
Content-Type: text/html
Set-Cookie: ASPSESSIONIDQQGGGNCG=LKLDFFKCINFLDMFHCBCBMFLJ; path=/
Cache-control: private
空行
<HTML>
<BODY>
......
上面的响应消息中的第一行为状态行,紧跟状态行后面的内容是消息头部分,
接着是一个空行,然后是实体内容。 - HTTP消息头
HTTP请求和HTTP响应都使用消息头来描述HTTP消息本身的信息。
消息头
消息头部分由一系列的行组成,每行都包含一个头字段名称,然后依次是冒号、空格、值、回车和换行符。
消息头字段名是不区分大小写的,但习惯上将每个单词的第一个字母大写。
按照其作用分类,消息头又可以分为通用消息头、请求头、响应头、实体头四类。
通用消息头 既能用于请求消息中,也能用于响应消息中,但与被传输的实体内容没有关系的常用消息头。
如 Date、Pragma。
请求头 用于在请求消息中向服务器传递附加消息,主要包括客户机可以接受的数据类型、压缩方法、语言,
以及客户机上保留的Cookie信息和发出该请求的超链接源地址等。
响应头 用于在响应消息中向客户端传递附加信息,包括服务程序的名称、要求客户端进行认证的方式、
请求的资源已移动到新的地址等。
实体头 用做实体内容的元信息,描述了实体内容的属性,包括实体信息的类型、长度、压缩方法、
最后一次修改的时间和数据的有效期等。
许多请求头字段都允许客户端的值部分指定多个可接受的选项,有时甚至可以对这些选项的首选项进行排名。
有些头字段可以出现多次。
二、请求行和状态行
- 请求行和状态行
1、请求行
请求消息的请求行中包括三个部分:请求方式、资源路径,
以及所使用的HTTP协议版本,各个部分用空格分隔,
语法格式为:
请求方式 资源路径 HTTP版本号<CRLF>
其中<CRLF>表示回车和换行这两个字符的组合。HTTP的请求方式包括
POST、HEAD、OPTIONS、DELETE、TRACE、PUT、GET,名称全部大写。
2、状态行
响应消息的状态行中包括三个部分:HTTP协议的版本号、一个表示成功或者失败的整数代码(状态码)
和对状态码进行描述的文本信息,各部分用空格分隔,语法格式如下:
HTTP版本号 状态码 原因叙述<CRLF>
借助Telnet程序直观地体验请求行和状态行 - 使用GET和POST方式传递参数
在URL地址后面可以附加一些参数,每个参数由参数名和参数值组成,参数值与参数名之间用等号(=)分隔,
各个参数之间用&分隔,URL地址和整个参数部分之间用问号(?)分隔,如下所示:
http://localhost/servlet/ParamsServlet?param1=abc¶m2=xyz
GET方式
在浏览器地址栏中直接输入某个URL地址、单击网页上一个超链接、
将网页上的<form>表单的method属性设置为"GET"、没有设置method属性(默认值为"GET"),
浏览器将使用GET方式发送请求。
使用GET方式传送的数据量是有限的,一般限制在1KB以下。
POST方式
如果网页上的<form>元素的method属性设置为"POST",浏览器将使用POST方式提交表单内容,
并把各表单字段元素及其数据作为HTTP消息的实体内容发送给Web服务器,
而不是作为URL地址的参数传递,
使用POST方式传送的数据量比使用GET方式传送的数据量要大得多。 - 响应状态码
响应状态码用于表示服务器对请求的各种不同处理结果和状态,它是一个三位的十进制数。
响应状态码可归为5种类别,使用最高位为1到5来进行分类。
1、100~199
表示成功接收请求,要求客户端继续提交下一次请求才能完成整个处理过程。
2、200~299
表示成功接收请求并已完成整个处理过程。
3、300~399
为完成请求,客户端需进一步细化请求。例如,请求的资源已经移动一个新地址。
4、400~499
客户端的请求有错误。
5、500~599
服务器端出现错误。
三、通用信息头
- 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-maxage等。
在一个Cache-Control头字段中可以设置多个取值,例如
Cache-Control: no-store,no-cache,must-revalidate
public 文档可以被任何代理和客户机缓存。
private 文档只能够被保存在单个用户的私有缓存中。
no-cache 如果no-cache后没有指定字段名,则客户机和代理服务器不应该缓存该文档,
在no-cache后也可以指定一个或多个其他的头字段名,这样代理服务器可以缓存该页面内容
来对以后的请求进行响应,但响应消息中不能包含no-cache后指定的头字段。
no-store 请求和响应的信息都不应被存储在对方的磁盘系统上。
must-revalidate 对于客户机的每次请求,代理服务器必须向服务器验证缓存的文档是否过时。
proxy-revalidate 除了只能用于共享缓存外,其作用与must-revalidate相同。
max-age=xxx 应该在xxx秒后认为文档过时,这可以代替Expires头的作用。
s-max-age=xxx 在代理服务器中缓存的文档(通常称之为共享缓存)在xxx秒后过时。 - Connection
Connection头字段用于指定处理完本次请求/响应后,客户端与服务器是否还要继续保持连接。
当Connection请求头的值为Keep-Alive时,客户端通知服务器返回本次请求结果后继续保持连接;
当Connection请求头的值为close时,客户端通知服务器返回本次请求结果后关闭连接。 - Date
Date头字段用于表示HTTP消息产生的当前时间。服务器回送的正常响应消息中,应该总是设置Date头字段。
如果客户机发送的请求消息中包含有实体内容,也需要设置Date头字段。
Date头字段的设置值必须为GMT格式。 - Pragma
Pragma头字段的设置值只能固定为no-cache,即Pragma:no-cache。
当Pragma头字段用于响应消息时,指示HTTP1.0客户机不要缓存文档;
当用于请求消息时,指示代理服务器必须返回一个最新的文档,而不能用缓存的文档。 - Trailer
对于放置在实体内容部分之后的头字段,需要在消息头中使用Trailer字段说明。 - Transfer-Encoding
如果HTTP消息的实体内容部分采用了某种传输编码方式,Transfer-Encoding头字段指定该传输编码方式,
如果设置值为chunked,用于把整个消息体分成一连串的分段后再进行传输。 - Upgrade
Upgrade头字段允许客户机指定它所希望将当前协议切换到的通讯协议,
对于101(切换协议)响应码,服务器必须使用Upgrade头字段指定切换的协议,例如,
Upgrade: HTTP/2.0, SHTTP/1.3 - Via
Via头字段用于指定HTTP消息所途径的中介代理服务器名称和所使用的协议,例如,
Via: HTTP/1.1 Proxy1, HTTP/1.1 Proxy2 - Warning
Warning头字段主要用于说明其他头字段和状态码不能说明的一些附加警告信息。
四、请求头
- Accept
Accept头字段用于指出客户端程序能够处理的MIME(Multipurpose
Internet Mail Extension,多用途Internet邮件扩展)类型。例如:
Accept: text/html,image/* - Accept-Charset
Accept-Charset头字段用于指出客户端程序可以使用的字符集,例如:
Accept-Charset: ISO-8859-1,UNICODE-1-1 - Accept-Encoding
Accept-Encoding头字段用于指定客户机能够进行解码的数据编码方式,
这里的编码方式通常是指某种压缩方式。例如:
Accept-Encoding: gzip,compress - Accept-Language
Accept-Language头字段用于指定客户机期望服务器返回哪个国家语言的文档。例如:
Accept-Language: en-gb,zh-cn - Authorization
当客户端访问受口令保护的网页文件时,Web服务器会发送401(Unauthorized)响应状态码和
WWW-Authorizate响应头,要求客户机使用Authorization请求头来应答。
有两种认证方式:分别是BASIC和DIGEST。
对于BASIC验证方式,客户端需要把冒号(:)分隔的用户名和密码进行Base64编码之后传送给Web服务器。
对于DIGIST验证方式,服务器首先向浏览器发送一些将用于验证过程的信息及附加信息,
浏览器将这些信息与用户名和密码以及某些其他信息进行混合后,再执行MD5散列算法,
并将散列算法的结果和附加信息一起以明文文本通过网络发送到服务器,
服务器也使用与客户端同样的信息和附加信息验证过程,对它所保存的客户端密码执行散列算法,
然后,将它的计算结果与客户端的计算结果比较,只有这两个数字完全相同时才允许访问。 - Expect
Expect头字段用于指定客户机请求服务器采取的特殊行动,如100-continue。 - From
From头字段用于指定请求发送者的E-mail地址。 - Host
Host头字段用于指定资源所在的主机名和端口号。例如:
Host: localhost:8080 - If-Match
服务器使用如下字段传送实体标签:
ETag: "xyzzy"
客户端使用If-Match头字段附带以前缓存的实体标签内容,例如:
If-Match: "xyzzy", "r2d2xxxx", "c3piozzzz"
如果客户机使用的是GET请求方式,服务器检索If-Match头中的实体标签内容,
并与服务器端的代表当前网页内容特征的实体标签内容进行比较。如果两者相同,
则表示网页内容没有修改,Web服务器不返回网页内容,让客户机仍然使用以前缓存的网页内容。
否则,服务器返回新的网页文件内容和新的实体标签内容头字段。
如果客户机使用的PUT请求方式,即表示要更新服务器上的网页内容,服务器检索If-Match头中的实体标签内容,
并与服务端的代表当前网页内容特性的实体标签内容进行比较。如果两者相同,则表示网页内容没有更改,
客户机可以更新网页内容。否则,说明网页内容已经被修改过,不允许PUT方法成功执行。 - If-Modified-Since
当用户再次访问已缓存的页面时,只有该文档至某个指定的时间以来发生过更改,
客户机才有必要下载此文档。If-Modified-Since请求头用于指定这个时间,其设置值为GMT格式。 - If-None-Match
If-None-Match头字段的作用与If-Match头字段的作用正好相反。 - If-Range
If-Range头字段只能伴随着Range头字段一起使用,其设置值可以是实体标签或HTTP的GMT格式的时间。
如果设置为实体标签,且该标签内容与服务器端的代表当前网页内容特征的实体标签内容相同,
则服务器按Range头的要求返回网页中的部分内容,否则,服务器返回当前网页的所有内容。
如果设置为HTTP的GMT格式的时间,只有自从这个时间以来,服务器上保存的网页文件没有发生修改,
服务器按Range头的要求返回网页中的部分内容,否则,服务器返回当前网页的所有内容。 - If-Unmodified-Since
If-Unmodified-Since头字段一般只用于PUT方式,其设置值为HTTP的GMT格式,
作用与If-Modified-Since正好相反。 - Max-Forwards
Max-Forwards头字段指定当前请求可以途径的代理服务器数量,每经过一个代理服务器,次数值就减一。 - Proxy-Authorization
除了针对代理服务器的用户信息认证外,Proxy-Authorization头字段的
作用与用法完全与Authorization头字段相同。 - Range
Range头字段用于指定服务器只需返回文档中的部分内容及内容范围。
Range头有以下几种使用格式:
1、Range:bytes=100-599
2、Range:bytes=100-
3、Range:bytes=-100 - Referer
浏览器向服务器发出的请求,可能是直接在浏览器地址栏中输入URL而发出,
也可能是单击另一个网页上的超链接而发出的。
对于第二种情况,浏览器使用Referer头字段指定发出请求的超链接(超链接所在网页)的URL。 - TE
TE头字段用于指定客户机可接受的扩展传输编码类型(除chunked之外的类型)和
使用chunked传输编码类型时是否允许使用Trailer头字段。例如:
TE: trailers, deflate - User-Agent
User-Agent头字段用于指定浏览器或其他客户端程序的类型和名称,
以便服务器针对不同类型的浏览器而返回不同的内容。例如:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)
五、响应头
- Accept-Range
Accept-Range头字段用于说明当前Web服务器是否接受Range请求和Range请求中指定的数据的单位。
例如:
Accept-Range: none
Accept-Range: bytes - Age
Age头字段用于指出当前网页文档可以在客户机或代理服务器中缓存的有效时间,
设置值是一个以秒为单位的时间数,例如:
Age: 315315315
客户机再次访问已缓存的某个网页文档内容时,先使用当前的时间值减去服务器上次返回该网页时
所设置的Date头字段的时间值,如果结果值小于服务器上次返回该网页时所设置的Age头字段的
时间值,客户机直接使用缓存中的网页内容。否则,客户机才向服务器发出针对该页面的访问请求。 - Etag
Etag头字段用于向客户机传送代表实体内容特征的标记信息,这些标记信息称为实体标签,
例如:Etag: b38b9-17dd-367c5dcd - Location
Location头字段用于通知客户机应该到哪个新的地址去获取文档。
状态码为300-399的响应消息都应该使用Location头字段将新的文档地址告诉给客户机,
以便客户机自动重新连接新地址并检索新文档。 - Proxy-Authenticate
除了是针对代理服务器的用户信息认证外,Proxy-Authenticate头字段的作用与用法与
WWW-Authenticate头字段完全相同。 - Retry-After
Retry-After头字段用于告诉客户机可以在什么时间重复发出刚才的请求,
需要与503(Service Unavailable)响应状态码结果使用。例如:
Retry-After: Tue, 11 Jul 2000 18:23:51 GMT - Server
Server头字段用于指定服务器软件的产品名称。例如:
Server: Microsoft-IIS/5.0 - Vary
Vary头字段用于指定影响了服务器所产生的响应内容的那些请求头字段名,例如:
Vary: Accept-Language - WWW-Authenticate
当客户端访问受口令保护的网页文件时,服务器需要结合采用401(Unauthorized)响应状态码和
WWW-Authenticate响应头,指示客户端应该在Authentication请求头中以什么样的认证方式
提供用户名和密码信息。WWW-Authenticate响应头中可以指定两种认证方式:BASIC和DIGEST。
六、实体头
- Allow
Allow头字段用于指定客户端请求的资源所支持的请求方式(如GET、POST等)。 - Content-Encoding
Content-Encoding头字段用于指定实体内容的压缩编码方式。 - Content-Language
Content-Language头字段用于指定返回的网页文档的国家语言类型,
其设置值应该是zh-cn、en-us、ja等国家语言的标准名称。 - Content-Length
Content-Length头字段用于标识实体内容的长度(字节数),浏览器与Web服务器之间使用持久
(keep-alive)的HTTP连接时,这个头字段在非chunked传输编码的响应消息中是必不可少的。 - Content-Location
Content-Location头字段用于指定响应消息中所封装的实体内容的实际位置路径,例如:
Content-Location:localhost:8080/java_cn.html - Content-MD5
Content-MD5头字段用于指定实体内容的MD5算法算出的数字摘要的base64编码结果,
以提供实体内容的完整性检查。 - Content-Range
Content-Range头字段用于指定服务器返回的部分实体内容的位置信息。只有客户机使用了Range请求头
要求服务器返回实体的部分内容时,服务器的响应头中才应包含Content-Range头。例如:
Content-Range: bytes 2543-4532/7898 - Content-Type
MIME最初是用于解决邮件传输系统中的数据格式问题的,
因为通过HTTP协议传输的数据也有各种类型,所以,HTTP也采用MIME来标识不同的数据类型。
在<Tomcat主目录>/conf目录下的web.xml文件中的设置MIME映射将对所有的Web应用程序都起作用,
而在某个Web应用程序的web.xml文件中的设置MIME映射只对该Web应用程序起作用。
MIME类型包含主类型和子类型,两者之间用“/”分隔。
Content-Type头中的MIME类型后面还可以指定响应内容所使用的字符集编码,
两者之间用分号(;)和空格隔开,例如,Content-Type:text/html;charset=GB3212。
如果Content-Type头中没有指定字符集编码类型,则默认使用ISO-8859_1(Latin)。 - Expires
Expires头字段用于指定当前文档应该在什么时候被认为过期,浏览器到那个时候以后不能再
继续使用本地缓存,而是在有需要时应该向服务器发出新的访问请求。 - Last-Modified
Last-Modified头字段用于指定文档的最后更改时间,设置值为GMT格式。
七、扩展头
- 扩展头
在HTTP消息中,也可以使用一些在HTTP1.1正式规范里没有定义的头字段,
这些头字段统称为自定义的HTTP头或扩展头。 - Refresh
Refresh头字段用于告诉浏览器过多少秒后自动刷新页面,例如:
Refresh: 1
在Refresh头字段的时间值后面还可以增加一个URL参数,时间值与URL之间用分号(;)分隔,
这将让浏览器在指定的时间值后跳转到其他网页,而不是刷新当前页面。例如:
Refresh: 1;url=http://localhost:8080/java_new.jsp - Content-Disposition
假如服务器希望浏览器不是直接处理响应的实体内容,而是可以让用户选择将响应的实体内容保存到一个文件中,
这就需要使用Content-Disposition头字段。
Content-Disposition指定了接收程序处理数据内容的方式,有inline和attachment两种标准方式,
inline表示直接处理,而attachment则要求用户干预并控制接收程序如何处理数据内容。
如果将Content-Disposition设置为attachment,在其后还可以指定filename参数。
在设置Content-Disposition头字段之前,一定要设置指定Content-Type头字段。
Content-Type: application/octet-stream
Content-Disposition: attachment;filename=aaa.zip