一、基本概念
HTTP通信过程包括从客户端发往服务器端的请求及从服务端返回客户端的响应。
用于HTTP协议交互的信息被称为HTTP报文,请求端的HTTP报文是请求报文,响应端的HTTP报文是响应报文。
HTTP报文本身是由多行(用CR+LF作换行符)数据构成的字符串文本。
-
请求报文
请求报文是由请求方法、请求URI、协议版本、可选的请求首部字段和内容实体构成的。
-
响应报文
响应报文基本上是由协议版本、状态码、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成。
二、HTTP请求方法
HTTP方法指定请求的资源按期望产生某种行为。
-
GET:获取资源
GET方法用来请求访问已被URI识别的资源。制定的资源经服务器端解析后返回响应内容。也就是说,如果请求的是文本资源,那就保持原样返回;如果是像CGI(Common Gateway Interface,通用网管接口)那样的程序,则返回执行后的结果。 -
POST:传输实体的主体
POST方法用来传输实体的主体。
虽然用GET方法也能传输实体的主体,但是一般不用GET方法进行传输,而是用POST方法。虽说两者功能很像,但是POST的主要目的不是获取响应的主体内容。 -
HEAD:获取报文首部
HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的日期时间等。 -
OPTIONS:询问支持的方法
OPTIONS方法用来查询针对请求的URI制定的资源支持的方法。 -
PUT:传输文件
PUT方法用来传输文件。就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求的URI制定的位置。
但是鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题。因此一般的Web网站不采用该方法。若配合Web应用程序的验证机制,或者架构设计采用REST标准的同类Web网站,可能使用PUT方法。 -
DELETE:删除文件
DELETE方法用来删除文件,是与PUT相反的方法。DELETE方法按请求URI删除指定的资源。
但是,HTTP/1.1的DELETE方法本身和PUT方法一样不带验证机制,所以一般的Web网站也不使用DELETE方法。当配合Web应用程序的验证机制,或遵守REST标准时还是有可能会开放使用的。 -
TRACE:追踪路径
TRACE方法是让Web服务器端将之前的请求通信环回给客户端的方法。
发送请求时,在Max-ForWords首部字段中填入数值,每经过一个服务器端就将该数字减1,当数值刚好见到0时,就停止继续传输,最后接收到请求的服务器端则返回状态码200 OK的响应。
客户端通过TRACE方法可以查询发送出去的请求是怎样被加工修改的。这是因为,请求要想链接到源目标服务器可能会通过代理中转,TRACE方法就是用来确认连接过程中发生的一系列操作。
但是TRACE方法本来就不常用,还容易引发CST(Cross—Site Tracing,跨站追踪)攻击,通常就更不会用到了。 -
CONNECT:要求用隧道协议连接代理
CONNECT方法要求在于代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL和TLS协议把通信内容加密后经网络隧道传输。
三、HTTP请求URI指定方式
当客户端请求访问资源而发送请求时,URI需要将作为请求报文中的请求URI包含在内。指定请求URI的方式有以下几种:
- URI为完整的请求URI
GET http://hackr.jp/index.html HTTP/1.1
- 在首部字段Host中写明网络域名或IP地址
GET /index.html HTTP/1.1
Host:hackr.jp
- 如果不是访问特定资源而是对服务器本身发起请求,可以用一个*来代替请求URI
OPTIONS * HTTP/1.1 (查询HTTP服务器端支持的HTTP方法种类)
四、HTTP响应状态码
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误。
状态码如200 OK
,以3位数字和原因短语组成。数字中的第一位指定了响应类别,后两位无分类。响应类别有以下5种。
-
2XX 成功 (2XX的响应结果表明请求被正常处理了)
-
200 OK
表示从客户端发来的请求在服务端被正常处理了。
在响应报文内,随状态码一起返回的信息会因方法的不同而发生改变。比如,使用GET方法时,对应请求资源的实体会作为响应返回;而使用HEAD方法时,对应请求资源的实体首部不随报文主体作为响应返回(即在响应中只返回首部,不会返回实体的主体部分)。 -
204 No Content
该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。
比如,当浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不更新。
一般在只需要从客户端往服务器发送消息,而对客户端不需要发送新消息内容的情况下使用。 -
206 Partial Content
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。
响应报文中包含由Content-Range
指定范围的实体内容。
-
-
3XX 重定向 (3XX响应结果表明浏览器需要执行某些特殊的处理以正确处理请求)
-
301 Moved Permanently
永久性重定向
该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。也就是说,如果已经把资源对应的URI保存为书签了,这时应该按Location首部字段提示的URI重新保存。 -
302 Found
临时性冲定向
该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问。和301状态码相似,但302状态码代表的资源不是被永久移动,只是临时性质的。比如,用户把URI保存成书签,不会像301状态码那样去更新书签,而是仍旧保留返回302状态码的页面对应的URI。 -
303 See Other
该状态码表示由于对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。
303状态码和302状态码有着相同的功能,但303状态码明确表示客户端应该采用GET方法获取资源,这点与302状态码有所区别。
比如,当使用POST方法访问CGI程序,其执行后的处理结果是希望客户端能以GET方法重定向到另一个URI上去时,返回303状态码。虽然302Found状态码也可以实现相同的功能,但这里使用303状态码是最理想的。 -
304 Not Modified
该状态码表示客户端发送附带条件的请求时,服务端允许请求访问资源,但未满足条件的情况。
304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系。 -
307 Temporary Redirect
临时重定向,该状态码与302Found有着相同的含义。尽管302标准禁止POST变换成GET,但实际使用时大家并不遵守。
307会遵守浏览器标准,不会从POST变成GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。
PS:当301、302、303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。
301、302标准是禁止将POST方法改变成GET方法的,但实际中使用时大家都会这么做。 -
-
4XX 客户端错误 (4XX的响应结果表明客户端是发生错误的原因所在)
-
400 Bad Request
该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像200OK一样对待该状态码。 -
401 Unauthorized
该状态码表示发送的请求需要有通过HTTP认证的认证信息。另外若之前已进行过1次请求,则表示用户认证失败。
返回含有401的响应必须包含一个适用于被请求资源的首部用以质询用户信息。当浏览器初次接收到401响应,会弹出认证用的对话窗口。
-
403 Forbidden
该状态码表示对请求资源的访问被服务器拒绝了。
未获得文件系统的访问权限,访问权限出现某些问题等情况都会返回403响应。 -
404 Not Found
该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用。
-
-
5XX 服务器错误 (5XX的响应结果表明服务器本身发生错误)
-
500 Internel Server Error
该状态码表明服务器端在执行请求时发生了错误,也可能是Web应用存在的bug或某些临时的故障。 -
503 Service Unavailable
该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
如果事先得知解除以上状况需要的时间,最好写入Retry-After首部字段再返回给客户端。
-
PS:状态码和状态的不一致:
不少返回的状态码响应都是错误的,但是用户可能察觉不到这点。
比如web应用程序内部发生错误,状态码依然返回 200 OK
,这种情况也经常遇到。
五、HTTP首部字段
-
HTTP首部字段结构:
首部字段名:字段值
当HTTP报文首部中出现了两个或两个以上具有相同首部字段名时会怎么样?
这种情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能并不一致。有些浏览器会优先处理第一次出现的首部字段,而有些会优先处理最后出现的首部字段。 -
HTTP首部字段类型:
3.1 HTTP首部字段根据实际用途被分为通用首部字段、请求首部字段、响应首部字段和实体首部字段。
-
通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。-
Cache-Control
控制缓存的行为 -
Connection
逐跳首部、连接的管理 -
Date
创建报文的日期时间 -
Pragma
报文指令 -
Trailer
报文末端的首部一览 -
Transfer-Encoding
指定报文主体的传输编码方式 -
Upgrade
升级为其他协议 -
Via
代理服务器的相关信息 -
Warning
错误通知
-
-
请求首部字段(Request Header Fields)
从客户端向服务器发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。-
Accept
用户代理能够处理的媒体类型以及媒体类型的优先级 -
Accept-Charset
用户代理支持的字符集以及字符集的优先级 -
Accept-Encoding
用户代理支持的内容编码及内容编码的优先级 -
Accept-Language
用户代理能够处理的自然语言集,以及自然语言集的优先级 -
Authorization
用户代理的认证信息(证书值) -
Expect
告知服务器,期望出现的某种特定行为 -
From
告知服务器使用用户代理的用户的电子邮件地址 -
Host
告知服务器,请求的资源所处的互联网主机名和端口号 -
If-Match
比较实体标记(ETag) -
if-Modified-Since
比较资源的更新时间 -
if-None-Match
比较实体标记(与if-Match相反) -
if-Range
资源未更新时发送实体Byte的范围请求 -
if-Unmodified-Since
比较资源的更新时间(与if-Modified-Since相反) -
Max-Forwards
最大传输逐跳数 -
Proxy-Authorization
代理服务器要求客户端的认证信息 -
Range
实体的字节范围请求 -
Referer
对请求中URI的原始获取方法 -
TE
传输编码的优先级 -
User-Agent
HTTP客户端程序的信息
PS:Host首部字段在HTTP/1.1规范内是唯一一个必须被包含在请求内的首部字段,和以单台服务器分配多个域名的虚拟主机的工作机制密切关联。
若服务器未设定主机名,那直接发送一个空值即可Host:
-
-
响应首部字段(Response Header Fields)
从服务器向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。-
Accept-Ranges
服务器是否能处理范围请求,bytes表示能,none表示不能 -
Age
响应已经产生了多长时间。HTTP/1.1规定缓存服务器在创建响应时必须包含Age首部 -
ETag
资源的实体标识 -
Location
客户端应重定向到指定URI,基本配合3XX
响应出现 -
Proxy-Authenticate
代理服务器对客户端的认证信息 -
Reter-After
对再次发起请求的时机要求 -
Server
HTTP服务器的安装信息 -
Vary
代理服务器缓存的管理信息 -
服务器对客户端的认证信息
-
-
实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。 补充了资源内容更新时间等与实体有关的信息。-
Allow
资源可支持的HTTP方法 -
Content-Encoding
实体主体的适用的编码方式 -
Content-Language
实体主体的自然语言 -
Content-Length
实体主体的大小(单位:字节) -
Content-Location
替代对应资源的URI -
Content-MD5
实体主体的报文摘要 -
Content-Range
实体主体的位置范围 -
Content-Type
实体主体的媒体类型 -
Expires
实体主体过期的日期时间 -
Last-Modified
资源的最后修改日期时间
-
-
为Cookie服务的首部字段
-
Set-Cookie
当服务器准备开始管理客户端的状态时,会事先告知各种信息。
Set-Cookie:status=enable; expires=Tue, 05 Jul 2014 08:22:31 GMT; => path=/;domain=.hackr.jp;
NAME=VALUE
赋予Cookie的名称和其值(必须项)
expires=DATE
Cookie的有效期,若不明确指定则默认为浏览器关闭前为止
path=PATH
将服务器上的文件目录作为cookie的适用对象(若不指定则默认为文档所在的文件目录)
domain=域名
作为Cookie适用对象的域名,若不指定则默认为创建Cookie服务器的域名。
secure
仅在HTTPS安全通信时,才可以发送Cookie.
HttpOnly
加以限制,使JavaScript脚本无法获取Cookie。
Cookie
Cookie:status=enable
首部字段Cookie会告知服务器,当客户端想获得HTTP状态管理支持时,就会在请求中包含从服务器接收到的Cookie.接收到多个Cookie时,同样可以以多个Cookie形式发送
-
3.2 HTTP首部字段根据有代理时的不同行为,分成2种类型。
-
端到端首部(End-to-end Header)
分在此类别中的首部字段会转发给请求/响应的最终接受目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。 -
逐跳首部(Hop-by-hop Header)
分在此类别中的首部只对单次转发有效,会因通过缓存或代理而不再转发。
HTTP/1.1和以后的版本中,如果要使用Hop-by-hop首部,需提供Connection首部字段。
下面列举了HTTP/1.1中的逐跳首部字段。除这8个首部字段之外,其他所有字段都属于端到端首部字段。Connection
Keep-Alive
Proxy-Authenticate
Proxy-Authorization
Trailer
TE
Transfer-Encoding
Upgrade
参考资料:《图解HTTP》
[2016.04.21]