HTTP学习文档
Writed by Vindeselly
Web浏览器、服务器和相关的Web应用程序都是通过HTTP相互通信的。HTTP是现代全球因特网中使用的公共语言。HTTP协议是TCP/IP的应用层协议,使用TCP的80端口。
Web服务器是Web资源的宿主,Web资源是Web内容的源头。最简单的Web资源就是Web服务器文件系统中的静态文件。但资源不一定非得是静态文件。资源还可以是根据需要生成内容的软件程序。
英特网上有数千种不同的数据类型,HTTP仔细的给每种要通过Web传输的对象都打上了名为MIME类型的数据格式标签。Web服务器会为所有的HTTP对象数据附加一个MIME类型。当Web浏览器从服务器中取回一个对象时,会查看相关的MIME类型,看看他是否值得应该如何处理这个对象。
MIME类型是一种文本标记,表示一种主要的对象类型和一个特定的子类型,中间由一条斜杠来分割。
例如:
HTML格式的文本文档由text/html类型来标记
普通的ASCII文本文档由text/plain类型类标记
JPEG格式的图片为image/jpeg类型
GIF格式的图片为image/gif类型
服务器资源名称被称为统一资源标识符(Uniform Resource Identifier,URI)。URI就像因特网上的邮政地址一样,在世界范围内唯一标识并定位资源。URI有两种形式,分别称为URL和URN。
统一资源定位符(URL)是资源标识符最常见的形式。URL描述了一台特定服务器上某资源的特定位置。它们可以明确说明如何从一个精确、固定的位置获取资源。大部分URL都遵循一种标准格式,这种格式包含三个部分:
1) URL的第一部分被称为方案(scheme),说明了访问资源所使用的协议类型。这部分通常就是HTTP协议(http://)。
2) 第二部分给出了服务器的因特网地址(比如,www.baidu.com)。
3) 其余部分指定了Web服务器上的某个资源(比如,/specials/saw-blade.gif)。
URI的第二种形式就是统一资源名(URN)。URN是作为特定内容的唯一名称使用的,与目前的资源所在地无关。使用这些与位置无关的URN,就可以将资源四处搬移。通过URN,还可以用同一个名字通过多种网络访问协议来访问资源。
一个HTTP事务由一条(从客户端发往服务器的)请求命令和一个(从服务器发回客户端的)响应结果组成。这种通信是通过名为HTTP报文(HTTP message)的格式化数据块进行的。
图1.1 包含请求及响应报文的HTTP事务
HTTP支持击中不同的请求命令,这些命令被称为HTTP方法(HTTPmethod)。每条HTTP请求报文都包含一个方法。这个方法会告诉服务器要执行什么动作。一些常见的方法:
1)GET 从服务器向客户端发送命名资源
2)PUT 将来自客户端的数据存储到一个命名的服务器资源中去
3)DELETE 从服务器中删除命名资源
4)POST 将客户端数据发送到一个服务器网关应用程序
5)HEAD 仅发送命名资源响应中的HTTP首部
每条HTTP响应报文返回时都会携带一个状态码。状态码是一个三位数字的代码,告知客户端请求是否成功,或者是否需要采取其他动作。伴随着每个数字状态码,HTTP还会发送一条解释性的“原因短语”文本,文本只是为了解释是给人看的,而状态码是给机器看的。无论文本是什么内容都不会影响机器处理同一状态码的动作。几种常见的状态码:
1)200 OK。文档正确返回
2)302 Redirect(重定向)。到其他地方去获取资源
3)404 Not Found(没找到)。无法找到这个资源
HTTP报文是由一行行的简单字符串组成的。HTTP报文都是纯文本,不是二进制代码,所以人们可以很方便地对其进行读写。图1.2显示了一个简单事务所使用的HTTP报文。
图1.2 简单文本结构组成的HTTP报文
从Web客户端发往Web服务器的HTTP报文称为请求报文(request message)。从服务器发往客户端的报文称为响应报文(response message),此外没有其他类型的HTTP报文。HTTP请求和响应报文的格式很类似。HTTP报文包含以下三个部分。
1) 起始行
报文的第一行就是起始行,在请求报文中用来说明做什么,在响应报文中说明出现了说明情况。
2) 首部字段
起始行后面有零个或多个首部字段。每个首部字段都包含一个名字和一个值,为了便于解析,两者之间用冒号(:)分隔。首部以一个空行结束。
3) 主体
空行之后就是可选的报文主体了,其中包含了所有类型的数据。起始行和首部都是文本形式且都是结构化的,而主体则不同,主体中可以包含任意的二进制数据也可以包含文本。
URL提供了一种定位因特网上任意资源的手段,但这些资源是可以通过各种不同的方案来访问的,因此URL语法会随方案的不同而有所不同。但是大部分的URL都遵循通用的URL语法,而且不同URL方案的风格和语法都有不少重叠。URL的通用格式如下:
几乎没有哪个URL中包含了所有这些组件。URL最重要的三个部分是方案(scheme)、主机(host)和路径(path)。
方案实际上是规定如何访问指定资源的主要标识符,它会告诉负责解析URL的应用程序应该使用什么协议。方案组件必须以一个字母符号开始,由第一个“:”符号将其与URL的其与部分分隔。方案名是不区分大小写。http=HTTP在意义上是等同的。
主机组件标识了因特网能够访问资源的宿主机器,端口组件标识了服务器正在监听的网络端口。
很多服务器要求用户名和密码才能登陆,比如FTP服务器。在书写URL的时候可以把用户名和密码输入,之间用冒号隔开。
URL的路径组件说明了资源位于服务器的什么地方。路径通常很像一个分级的文件系统路径。路径是服务器定位资源时所需的信息。可以用字符“/”将HTTP URL的路径组件划分成一些路径段。每个路径段都有自己的参数组件。
为了向应用程序提供它们所需的输入参数,一遍正确地与服务器进行交互,URL中有一个参数组件。这个组件就是URL中的名值对列表,由字符“;”将其与URL的其余部分分隔开。它们为应用程序提供了访问资源所需的所有附件信息。例如:
ftp://192.168.96.6/pub/gnu;type=d
或者多路径时:
http://www.baidu.com/hammers;sale=false/index.html;graphics=true
当访问一个类似于数据库服务的服务器时,可以使用查询组件来准确的定位目标。比如:
http://www.vindeselly.com/inventory-check.cgi?item=1245
这个例子表示查询一个条目为1245的目标。查询字符串时以一系列的“名/值”对的形式出现,名值对之间用字符“&”分隔,例如
http://www.vindeselly.com/inventory-check.cgi?item=1245&color=blue&size=large
假如资源的URL指向整个文本文档,但我们只需要其中的某个章节。为了引用部分资源或资源的一个片段,URL支持使用片段(frag)组件来表示一个资源内部的片段。这个组件挂在URL的右边,前面有一个字符“#”。例如:
http://www.joes-hardware.com/tools.html#drills
HTTP服务器通常只处理整个对象,而不是对象的片段,客户端不能将片段传送给服务器。浏览器从服务器获得了整个资源后,会根据片段来显示感兴趣的部分资源。
HTTP报文是在HTTP应用程序之间发送的数据块,这些数据块以一些文本形式的元信息(meta-information)开头,这些信息描述了报文的内容及含义,后面跟着可选的数据部分。
HTTP使用术语流入(inbound)和流出(outbound)来描述事务处理(transaction)的方向。报文流入源端服务器,工作完成之后,流回用户的Agent代理中。
HTTP报文不管是请求报文还是响应报文,所有报文都会向下游(downstream)流动。所有报文的发送者都在接收者的上游(upstream)。需要注意的是,没有报文会向上游流动。
HTTP报文时简单的格式化数据块,它们由三个部分组成:对报文进行描述的起始行(start line)、包含属性的首部(header)块,以及可选的、包含数据的主体(body)部分。
如图1.2中所示,起始行和首部就是由行分隔的ASCII文本。每行都以一个由两个字符组成的行终止序列作为结束,其中包括一个回车符和一个换行符。这个行终止序列可以写做CRLF。(虽然HTTP规范中说明应该用CRLF表示终止,但是稳健的应用程序也应该结束单个换行符作为行的终止)实体的主体或报文的主体是一个可选的数据块。与起始行和首部不同的是,主题中可以包含文本或二进制数据,也可以为空。
HTTP报文可以分两类:请求报文(requestmessage)和响应报文(response message)。请求报文会向Web服务器请求一个动作。响应报文会将请求的结构返回给客户端。两种报文的结构相同。
请求报文的格式:
响应报文的格式:
各部分的简要描述:
方法(method):客户端希望服务器对资源执行的动作
请求URL(request-URL):命名了请求资源,或者URL路径组件的完整URL
版本(version):报文所使用的HTTP版本,格式 HTTP/
状态码(status-code):这三位数字描述了请求过程中所发生的情况。每个状态码的第一个数字用于描述状态的一般类别(成功、出错等)
原因短语(reason-phrase):可读的描述状态码的文本,只对人类有效
首部(header):可以有零个或多个首部,每个首部都包含一个名字,后面跟着一个冒号(:),然后是一个可选的空格,接着是一个值,最后是一个CRLF。首部是由一个空行结束的,表示了首部列表的结束和实体主体部分的开始。
实体的主体部分(entity-body):实体的主体部分包含一个由任意数据组成的数据块。并不是所有的报文都包含实体的主体部分,有时报文只是以一个CRLF结束。
请求的起始行以方法作为开始,方法用来告知服务器要做什么。主要的方法一共有七种,但是,这些方法中有的包含主体,有的则不包含。
方法 |
描述 |
是否包含主体 |
GET |
从服务器获取一份文档 |
否 |
HEAD |
只从服务器获取文档的首部 |
否 |
POST |
向服务器发送需要处理的数据 |
是 |
PUT |
将请求的主体部分存储在服务器上 |
是 |
TRACE |
对可能经过代理服务器传送到服务器上去的报文进行追踪 |
否 |
OPTIONS |
决定可以在服务器上执行哪些方法 |
否 |
DELETE |
从服务器伤处一份文档 |
否 |
状态码用于告知客户端发生了什么事情,状态码是在每条响应报文的起始行中返回的。会返回一个数字状态和一个可读的状态。目前将状态码做了基本的分类如下:
整体范围 |
已定义范围 |
分类 |
100~199 |
100~101 |
信息提示 |
200~299 |
200~206 |
成功 |
300~399 |
300~305 |
重定向 |
400~499 |
400~415 |
客户端错误 |
500~599 |
500~505 |
客户端错误 |
几种常见的状态码:
状态码 |
原因短语 |
含义 |
200 |
OK |
成功。请求的所有数据都在响应主体中 |
302 |
Found |
在请求的URL已被移出时使用,响应的Location首部中应该包含资源现状所处的URL,但是,客户端应该使用Location首部给出的URL来临时定位资源。将来的请求仍应使用老的URL |
404 |
Not Found |
服务器无法找到所请求URL对应的资源 |
首部和方法配合工作,共同决定了客户端和服务器能做什么事情。通常首部可以分为以下五类:
1. 通用首部
这些事客户端和服务器都可以使用的通用首部。可以在客户端、服务器和其他应用程序之间提供一些非常有用的通用功能。例如:
Date: Mon, 4 Nov 2014 15:45:12 UTC
Date:提供了日期和时间标识,说明报文是什么时间创建的
Connection:允许客户端和服务器指定与请求/响应连接有关的选项
Via:显示了报文经过的中间节点(代理、网关)
2. 请求首部
请求首部是指在请求报文中有意义的首部。用于说明是谁或什么在发送请求、请求源自何处,或者客户端的喜好及能力。
1) 请求的信息性首部
Client-IP:提供了运行客户端的机器的IP地址
From:提供了客户端用户的E-mail地址
Host:给出了接收请求的服务器的主机名和端口号
Referer:提供了包含当前请求URI的文档的URL
2) Accept首部
Accept: */*
Accept:告诉服务器能够发送哪些媒体类型
Accept-Charset:告诉服务器能够发送哪些字符集
Accept-Encoding:告诉服务器能够发送哪些编码方式
3) 条件请求首部
Expect:允许客户端列出某请求所要求的服务器行为
Range:如果服务器支持范围请求,就请求资源的指定范围
4) 安全请求首部
Authorization:包含了客户端提供给服务器,以便对其自身进行认证的数据
Cookie:客户端用它向服务器传送一个令牌——他并不是真正的安全首部,但确实是隐含了安全功能
5) 代理请求首部
Max-Forward:在通往源端服务器的路径上,将请求转发给其他代理或网关的最大次数
Proxy-Authorization:与Authorization首部相同,但这个首部是在与代理进行认证时使用的
Proxy-Connection:与Connection首部相同,但这个首部是在与代理建立连接时使用的
3. 响应首部
响应报文有自己的响应首部集。响应首部为客户端提供了一些额外信息,比如谁在发送响应、响应者的功能,甚至与响应相关的一些特殊指令。
1) 响应的信息性首部
Age:(从最初创建开始)响应持续时间
Public:服务器为其资源支持的请求方法列表
Server:服务器应用程序软件的名称和版本
2) 协商首部
Accept-Ranges:对此资源来说,服务器可接受的范围类型
3) 安全响应首部
Set-Cookie:不是真正的安全首部,但隐含有安全功能;可以在客户端设置一个令牌,以便服务器对客户端进行标识
Proxy-Authenticate:来自代理的对客户端的质询列表
4. 实体首部
1) 实体的信息性首部
Allow:列出了可以对此实体执行的请求方法
Location:告知客户端实体实际上位于何处;用于将接收端定向到资源的位置(URL)
2) 内容首部
Content-Base:解析主体中的相对URL时使用的基础URL
Content-Encoding:对主体执行的任意编码方式
3) 实体缓存首部
Etag:与此实体相关的实体标记
Exprise:实体不再有效,要从原始的源端再次获取此实体的日期和时间