共11章计划一天学习2-3章。
1990年问世,HTTP/0.9
1996年5月,HTTP/1.0诞生,记载于RFC1945。
1997年1月,HTTP/1.1公布,是目前主流的HTTP协议版本,最初标准为RFC2068,修订后最新版本为RFC2616。
从低到高四层:数据链路层、网络层、传输层、应用层
应用层:决定了向用户提供应用服务时通信的活动。
传输层:TCP和UDP协议。提供处于网络连接中的两台计算机之间的数据传输。
网络层处理网络上流动的数据包。网络层传输单位为数据包。
数据链路层:处理连接网络的硬件部分。
IP:IP协议位于网络层。IP地址指明了节点被分配到的地址,MAC地址是指网卡所属的固定地址。使用ARP(地址解析协议)凭借MAC地址进行通信。ARP通过IP地址解析MAC地址。
TCP:TCP协议处于传输层,提供可靠的字节流服务。(TCP面向字节流,UDP面向报文)TCP确保可靠性,三次握手四次挥手。
DNS:域名解析服务DNS,应用层协议。提供域名到IP地址之间的解析服务,也提供IP地址反查域名服务。
URI:统一资源标识符
URL:统一资源定位符
使用HTTP协议时必定一端担任客户端角色,一端担任服务器角色。
请求必定由客户端发出,服务器端回复响应。
HTTP协议自身不具备保存之前发送过的请求或相应的功能。
为了实现期望的保存状态功能引入Cookie技术。
HTTP协议使用URI定位互联网上的资源。
如果不是访问特定资源而是对服务器本身发起请求,用*号代替请求URI。
GET:获取资源
用来请求访问已被URI识别的资源。指定的资源经服务器端解析后返回响应内容。经解析后返回说明,如果请求资源是文本,就保持原样返回,如果是CGI(通用网关接口)的程序,返回执行后的输出结果。
POST:传输实体主体
用来传输实体的主体,GET也可传输实体的主体,但一般不用GET方法进行传输。POST功能虽然与GET相似,但POST主要目的并不是获取响应的主体内容。
PUT:传输文件
用来传输文件,要求在请求报文的主体中包含文件内容,保存到请求URI指定的位置。存在安全性问题,一般不采用该方法。
HEAD:获取报文首部
与GET方法一样,但不返回报文主体部分。用于确认URI的有效性及资源更新的日期时间等。
DELETE:删除文件
用来删除文件,与PUT相反。按照请求URI删除指定资源。不带验证机制,不够安全。
OPTIONS:询问支持的方法
用来查询针对请求URI指定的资源支持的方法。
TRACE:追踪路径
让Web服务器端将之前的请求通信环回给客户端的方法。
发送请求时在Max-Forwards首部字段填入数值,每经过一个服务器端将该数字减1,减为0时停止传输。用来确认连接过程中发生的一系列操作。
不常用容易引发XST(Cross-Site Tracing,跨站追踪)攻击。
Connect:要求用隧道协议连接代理
要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。主要使用SSL (Secure Sockets Layers,安全套接层)和TLS(Transport Layer Security,传输层安全)协议把通信内容加密后经过网络隧道传输。
格式:CONNECT 代理服务器名:端口号 HTTP版本
向请求URI指定的资源发送请求报文时,采用称为方法的命令。
方法的作用:可以指定请求的资源按期望产生某种行为。
方法 | 说明 | 支持的HTTP协议 |
---|---|---|
GET | 获取资源 | 1.0、1.1 |
POST | 传输实体主体 | 1.0、1.1 |
PUT | 传输文件 | 1.0、1.1 |
HEAD | 获取报文首部 | 1.0、1.1 |
DELETE | 删除文件 | 1.0、1.1 |
OPTIONS | 询问支持的方法 | 1.1 |
TRACE | 追踪路径 | 1.1 |
CONNECT | 要求用隧道协议连接代理 | 1.1 |
LINK | 建立和资源之间的联系 | 1.0 |
UNLINK | 断开连接关系 | 1.0 |
HTTP协议的初始版本中,每进行一次HTTP通信就要断开一次TCP连接,增加了通信量开销。
持久连接:旨在建立一次TCP连接后进行多次请求和响应的交互。
好处:减少了TCP连接的重复建立和断开所造成的额外开销,减轻服务器端的负载。提高了Web页面的显示速度。
HTTP/1.1中,所有连接默认都是持久连接。
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并
收到响应才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。同时并行发送多个请求,不需要一个接一个等待响应。
HTTP是无状态协议,不对之前发生过的请求和响应的状态进行管理,无法根据之前的状态进行本次的请求处理。
无状态协议优点:不必保存状态,可以减少服务器CPU及内存资源的消耗,正是因为HTTP协议本身非常简单,才会被广泛应用在各种场景中。
Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端状态。
Cookie会根据从服务器端发送的响应报文内的Set-Cookie的首部字段信息,通知客户端保存Cookie。下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。
服务器端发现客户端发送来的Cookie后,会去检查是从哪一个客户端发送的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
发生Cookie交互示例
1 请求报文(不含Cookie信息的状态)
2 响应报文(服务器端生成Cookie信息)
3 请求报文(自动发送保存着的Cookie信息)
用于HTTP协议交互的信息被称为HTTP报文。请求端的HTTP报文叫做请求报文,响应端的叫做响应报文。
大致分为报文首部和报文主体两块,两者由空行(CR回车0x0d+LF换行0x0a)划分。不一定有报文主体。
HTTP在传输数据时可以按照数据原貌直接传输,也可以在传输过程中通过编码提升传输速率。通过在传输时编码,能有效处理大量访问请求。但会消耗更多的计算机资源。
报文
HTTP通信基本单位,8位组字节流,通过HTTP通信传输
实体
作为请求或响应的有效载荷数据被传输,内容由实体首部和实体主体组成。
把内容编码后的实体发送,客户端接收并解码。
常用内容编码:gzip(GNU zip)、conpress(Unix系统标准压缩)、deflate(zlib)、identity(不编码)
HTTP通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。传输大容量数据时,数据分块传输能实现浏览器逐步显示页面。该功能称为分块传输编码。
分块后,每一块都会用16进制来标记块的大小,最后一块使用0(CR+LF)来标记。
HTTP/1.1中存在传输编码机制,可在通信时按照某种编码方式传输,只定义作用于分块传输编码中。
在邮件中写入文字并添加多份附件是因为使用了MIME机制(多用途因特网邮件扩展)。
MIME机制允许处理文本、图片、视频等多个不同类型数据。
HTTP协议中也采纳了多部分对象集合,发送的一份报文可含有多类型实体。通常在图片或文本文件上传时使用。
Content-Type字段:HTTP报文中使用多部分对象集合时,需要在首部字段加上Content-type。
为解决网络中断导致下载过程中断的问题,需要一种可恢复的机制。
实现该功能需要指定下载的实体范围,指定范围发送的请求叫做范围请求。
首部字段Range:用来指定资源的byte范围。
针对范围请求,响应报文会返回状态码为206 Partial Content的响应报文。
如果服务器端无法相应范围请求,会返回状态码200OK和完整的实体内容。
同一个Web网站可能存在多份相同内容的页面,比如中文或英文版的Web页面。
当浏览器默认语言为英语或中文,访问相同URI的Web页面时,会显示对应的英文版或中文版的Web页面,这样的机制称为内容协商。
内容协商机制是指客户端和服务器端就相应的资源内容进行交涉,然后提供给客户端最为适合的资源。判断的基准:资源的语言、字符集、编码方式等。
内容协商的三种类型:
状态码负责表示客户端HTTP请求的返回结果、标记服务器端的处理是否正常、通知出现的错误等工作。
借助状态码用户可以知道服务器端是正常处理请求还是出现了错误。
类别 | 原因短语 | |
---|---|---|
1XX | informational(信息性状态码) | 接受的请求正在处理 |
2XX | Sucess(成功状态码) | 请求正常处理完毕 |
3XX | Redirection(重定向状态码) | 需要进行附加操作以完成请求 |
4XX | Client Error(客户端错误状态码) | 服务器无法处理请求 |
5XX | Server Error(服务器错误状态码) | 服务器处理请求出错 |
状态码种类繁多,常用大概只有14种。
请求被服务器端正常处理。
请求正常处理,但返回的响应报文不含实体的主体部分。
进行了范围请求,成功执行了这部分的GET请求。
3XX表明浏览器???需要执行某些特殊处理以正确处理请求。
永久性重定向。表明请求的资源已经被分配了新的URI,重新保存URI。
临时性重定向。表明请求的资源已经被分配了新的URI,希望用户能使用新的URI访问。用户将URI保存成书签,但不会像301出现时那样更新书签。
表明请求对应的资源存在着另一个URI,应该使用GET方法定向获取请求的资源。
客户端发送附带条件的请求时,服务器端允许请求访问资源,但未满足条件的情况。
304返回时,不包含任何响应的主体部分。
临时重定向,状态码与302 Found有相同含义。
表示请求报文中存在语法错误。错误发生时,需要修改请求内容再次发送请求。
表示发送的请求需要有通过HTTP认证的认证信息。若此前已进行1次请求,则表明用户认证失败。
必须包含一个适用于被请求资源的WWW Auhenticate首部用以质询用户信息。初次接受401会弹出认证用的对话窗口。
对请求资源的访问被服务器拒绝了,服务器无需给出拒绝详细理由。授权问题
服务器上无法找到请求的资源。也可以在服务器拒绝请求且不想说明理由时使用。
服务器在执行请求时发生错误,也可能是Web应用存在bug或某些临时故障。
服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
状态码和状况的不一致
不少返回的状态码响应都是错误的
蛤蛤蛤,毕业答辩了鸽了好多天,有点内疚了。
HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点。利用了虚拟主机(Virtual Host,又称虚拟服务器)的功能。
客户端使用HTTP协议访问服务器时,会经常采用www.hacker.jp这样的主机名和域名。
域名通过DNS服务映射到IP地址之后访问目标网站。当请求发送到服务器时,已经是IP地址形式访问。
当一台服务器托管了两个域名,收到请求时需要弄清究竟访问哪个域名。在相同IP地址下,虚拟主机寄存多个不同主机名和域名的Web网站,所以在发送HTTP请求时,必须在Host首部完整指定主机名和域名的URI。
HTTP通信时,除去客户端和服务器以外还有一些用于通信数据转发的应用程序,例如代理、网关和隧道。可以配合服务器工作。
这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给服务器。
代理服务器:接收客户端发送的请求转发给其他服务器。不改变请求的URI,会直接发送给前方持有资源的目标服务器。
级联多台代理服务器,请求和响应的转发经过数台的连接起来的代理服务器。需要附加Via首部字段以标记出经过的主机信息。
代理服务器选择的理由:利用缓存技术减少网络带宽的流量,组织内部针对特定网站的访问控制以获取访问日志为主要目的。
按两种基准分类:是否使用缓存,是否会修改报文。
缓存代理:预先将资源的副本(缓存)保存在代理服务器。代理再次接收到对相同资源的请求时,可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。
透明代理:转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理。反之对报文内容进行加工的代理被称为非透明代理。
(可搜索了解透明的概念)
利用网关可以由HTTP请求转化为其他协议通信。
网关工作机制和代理十分相似,网关能是通信线路上的服务器提供非HTTP协议服务。
利用网关能提高通信的安全性,可以在客户端与网关之间的通信线路上加密以确保连接的安全。例如:
①使用网关连接数据库,使用SQL语句查询数据。
②Web购物网站进行信用卡结算时,网管可以和信用卡结算系统联动。
隧道可按要求建立起一条与其他服务器的通信线路,使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。
隧道本身不解析HTTP请求,隧道会在通信双方断开连接时结束。
隧道本身是透明的,客户端不同在意隧道的存在。
指代理服务器或客户端本地磁盘内保存的资源副本,利用缓存可减少对源服务器的访问,节省了通信流量和通信时间。
缓存服务器是代理服务器的一种,归类在缓存代理类型中。当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。
缓存服务器的优势:利用缓存可避免多次从源服务器转发资源。客户端就近从缓存服务器上获取资源,源服务器不必多次处理相同请求。
即使存在缓存,也不能保证每次都会返回对同资源的请求。关系到被缓存资源的有效性问题。
源服务器资源更新时,如果还是使用不变的缓存,就会返回更新前的旧资源了。
即使存在缓存也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失败,缓存服务器将会再次从源服务器上获取新资源。
客户端浏览器存储缓存。IE浏览器为例,客户端缓存被称为临时网络文件,浏览器缓存有效就不必向服务器请求相同资源,可以直接从本地磁盘内读取。
和缓存服务器相同,判定缓存过期后,会向源服务器确认资源的有效性。判断浏览器缓存失效会再次请求新资源。
HTTP出现之前的协议:
HTTP普及之前,出现过各式各样的协议。
FTP(File Transfer Protocol)
文件传输协议,可追溯到1973年前。现在仍被广泛使用。
NNTP(Network News Transfer Protocol)
NetNews电子会议室内传送消息的协议,在1986年前后出现,已经不怎么使用了。
Archie
搜索anonymousFTP公开的文件信息的协议。1990年前后出现。现在不常使用。
WAIS(Wide Area Information Servers)
以关键词检索多个数据库使用的协议。1991年前后出现,不怎么使用了。
Gopher
查找与互联网连接的计算机内信息的协议。1991年前后出现,被HTTP协议 替代,不怎么使用了。
害,没人监督了最近进度超慢。
HTTP协议的请求和响应报文中必定包含HTTP首部。首部内容为客户端和服务器分别处理请求和响应提供所需要的信息。
HTTP请求报文:由方法、URI、HTTP版本、HTTP首部字段等部分构成。
HTTP响应报文:由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成。
HTTP首部字段是构成HTTP报文的要素之一。起到传递额外重要信息的作用。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
首部字段由首部字段名和字段值构成,中间用冒号“:”分隔。
首部字段名:字段值
例如:
Content-Type:text/html
字段值对应单个HTTP首部字段可以有多个值
Keep-Alive:timeout=15,max=100
若HTTP首部字段重复了会怎么样?
HTTP报文首部出现两个或两个以上具有相同首部字段名的情况在规范内尚未明确,根据浏览器内部处理逻辑的不同,结果可能不一致。有些会优先处理第一次出现的首部字段,有些会优先处理最后出现的首部字段。
根据实际用途,将HTTP首部字段分为以下4种类型。
通用首部字段(Generral Header Fields):请求报文和响应报文两方都会使用的首部。
请求首部字段(Request Header Fields):从客户端向服务器发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。
响应首部字段(Response Header Fields):服务器端向客户端返回响应报文时使用的首部。补充了请求的附加内容、客户端信息、相应内容相关优先级等信息。
实体首部字段(Entity Header Fields):针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
HTTP/1.1规范定义了如下47种首部字段
首部字段名 | 说明 |
---|---|
Cache-Control | 控制缓存的行为 |
Connection | 逐跳首部连接的管理 |
Date | 创建报文的日期时间 |
Pragma | 报文指令 |
Trailer | 保温末端的首部一览 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Upgrade | 升级为其他协议 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的自然语言 |
Authorization | Web认证信息 |
Expect | 期待服务器的特定行为 |
Form | 用户的电子邮箱地址 |
Host | 请求资源所在服务器 |
If-March | 比较实体标记(ETag) |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记(与If-March相反) |
If-Range | 资源为更新时发送实体Byte的范围请求 |
If-Unmodified-Since | 比较资源的更新时间(与If-Modified-Since相反) |
Max-Forward | 最大传输逐跳数 |
Proxy-Authorization | 代理服务器要求客户端的认证信息 |
Range | 实体的字节范围请求 |
Referer | 对请求中URI的原始获取方 |
TE | 传输编码的优先级 |
User-Agent | HTTP客户端程序的信息 |
首部字段名 | 说明 |
---|---|
Accept-Ranges | 是否接收字节范围请求 |
Age | 推算资源创建经过时间 |
Etag | 资源的匹配信息 |
Location | 令客户端重定向至指定URI |
Proxy-Authenticate | 代理服务器对客户端的认证信息 |
Retry-After | 对再次发起请求的时机要求 |
Server | HTTP服务器的安装信息 |
Vary | 代理服务器缓存的管理信息 |
WWW-Authenticate | 服务器对客户端的认证信息 |
首部字段名 | 说明 |
---|---|
Allow | 资源可支持的HTTP方法 |
Content-Encoding | 实体主体适用的编码方式 |
Content-Language | 实体主体的自然语言 |
Content-Length | 实体主体的大小(单位:字节) |
Content-Location | 替代对应资源的URI |
Content-MD5 | 实体主体的报文摘要 |
Content-Type | 实体主体的媒体类型 |
Expires | 实体主体过期的日期时间 |
Last-Modified | 资源的最后修改日期 |
在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段,还有Cookie、Set-Cookie和Content-Disposition等在其他RFC中定义的首部字段。
HTTP首部字段将定义成缓存代理和非缓存代理的行为,分成2种类型。
端到端首部(End-to-end Header)
分在此类别中的首部会转发给请求/响应对应的最终接受目标,且必须保存在由缓存生成的响应中,另外规定它必须被转发。
逐跳首部(Hop-by-hop Header)
分在此类别中的首部只对单词转发有效,会因通过缓存或代理而不再转发。HTTP/1.1和之后的版本中,如果使用hop-by-hop首部,需提供Connection首部字段。
8个逐跳首部字段:Connection、Keep-Alive、Proxy-Authenticate、Proxy-Authorization、Trailer、TE、Transfer-Encoding、Upgrade
请求和响应报文都会使用的首部。
通过指定首部字段Cache-Control的指令,能操作缓存的工作机制。
指令参数的可选的,多个指令之间用“,”分割。可以按照请求和响应分类。
public指令 (响应指令)
Cache-Control:public
使用public指令明确表明其他用户也可利用缓存。
private指令 (响应指令)
Cache-Control:private
指定private指令后,响应只以特定的用户作为对象,与public指令行为相反。
缓存服务器回对该特定用户提供资源缓存的服务,对其它用户发送过来的请求,代理服务器不会返回缓存。
no-cache 指令 (响应和请求)
使用no-cache指令的目的是为了防止从缓存中返回过期的资源。
客户端发送的请求中包含no-cache指令,则表示客户端不会接收缓存过的响应。“中间”的缓存服务器必须把客户端请求转发给源服务器。
如果服务器返回的响应中包含no-cache指令,那么缓存服务器不能对资源进行缓存。源服务器以后也将不再对缓存服务器请求中提出的资源有效性进行确认,且禁止缓存服务器对响应资源进行缓存操作。
Cache-Control:no-cache=Location
服务器返回响应中,如果报文的首部字段Cache-Control中对no-cache字段名具体指定参数值,那么客户端在接收到这个被指定参数值的首部字段对应的响应报文后,就不能使用缓存。(说这么绕呢?????????)换言之,无参数值的首部字段可以使用缓存。只能在响应指令中指定该参数。
no-store 指令 (响应和请求)
Cache-Control:no-store
使用no-store指令时,暗示请求或响应中包含机密信息
该指令规定缓存不能在本地存储请求或响应的任一部分。
no-cache代表不缓存过期资源,缓存会向源服务器进行有效期确认后处理资源。no-store是真正地不进行缓存。