文章目录
- 第一章、了解web及网络基础
- HTTP 的诞生
- 网络基础 TCP/IP
- TCP/IP 协议族
- 层次化的好处
- 应用层
- 传输层
- 网络层
- 链路层(又名数据链路层,网络接口层)
- 数据传输流举例:
- 与HTTP关系密切的协议:IP、TCP和DNS
- 负责传输的 IP 协议
- ARP协议作用
- 确保可靠性的 TCP 协议
- 负责域名解析的 DNS 服务
- 三种协议与 HTTP 协议的关系
- URI 和 URL
- 统一资源标识符 URI
- URI格式
- 统一资源定位符 URL
- 第二章、简单的HTTP协议
- 了解客户端和服务器通讯的过程
- 请求报文
- 响应报文
- HTTP 是不保存状态的协议
- 请求 URI 定位资源
- 告知服务器意图的 HTTP 方法
- GET :获取资源
- POST :传输实体主体
- PUT:传输文件
- HEAD:获得报文首部
- DELETE:删除文件
- OPTIONS:询问支持的方法
- TRACE:追踪路径
- CONNECT:要求用隧道协议连接代理
- 持久连接节省通信量
- 使用 Cookie 的状态管理
- 第三章、HTTP报文内的HTTP信息
- http报文
- 请求报文与响应报文
- 编码提升传输效率
- 报文主体与实体主体的差异
- 压缩传输的内容编码
- 分割发送的分块传输编码
- 发送多种数据的多部分对象集合
- 获取部分内容的范围请求
- 内容协商返回最合适的内容
- 第四章、返回结果的http状态码
- 状态码告知从服务器端返回的请求结果
- 2XX 成功
- 1. 200 OK
- 2. 204 No Content
- 3. 206 Partial Content
- 3XX 重定向
- 1. 301 Moved Permanently
- 2. 302 Found
- 3. 303 See Other
- 4. 304 Not Modified
- 5. 307 Temporary Redirect
- 4XX 客户端错误
- 1. 400 Bad Request
- 2. 401 Unauthorized
- 3. 403 Forbidden
- 4. 404 Not Found
- 5XX 服务器错误
- 1. 500 Internal Server Error
- 2. 503 Service Unavailable
- 第五章、与HTTP协作的web服务器
- 用单台虚拟主机实现多个域名
- 通信数据转发程序:代理、网关、隧道
- 1. 代理
- 使用代理服务器的理由
- 2. 网关
- 3. 隧道
- 保存资源的缓存
- 1. 缓存的有效期限
- 2. 客户端的缓存
- 第六章、HTTP首部
- HTTP 报文首部
- HTTP 首部字段
- HTTP首部字段传递重要信息
- 4 种 HTTP 首部字段类型
- 非HTTP/1.1首部字段
- End-to-end首部和Hop-by-hop首部
- 为Cookie服务的首部字段
- Set-Cookie与Cookie
- 第七章、确保web安全的htttps
- 通信加密
- 内容加密
- 查明对手的证书
- HTTPS(=HTTP+加密+认证+完整性保护)
- 公开秘钥加密方法
- HTTPS采用混合加密机制
- 证明公开秘钥正确性的证书
- 用以确认客户端的客户端证书
- HTTPS的安全通信机制
- SSL与TLS
- 第八章、确认访问用户身份的认证
- 何为认证
- 基于表单认证
- Session 管理及 Cookie 应用
- 基于http的功能追加协议
- 使用浏览器进行全双工通信的websocket
- 握手·请求
- 握手·响应
第一章、了解web及网络基础
HTTP 的诞生
以前的 HTTP 协议的出现主要是为了解决文本传输的难题。由于协议本身非常简单,于是在此基础上设想了很多应用方法并投入了实际使用。现在HTTP协议已经超出了Web这个框架的局限,被运用到了各种场景里。
网络基础 TCP/IP
TCP/IP 协议族
通常使用的网络是在TCP/IP协议族的基础上运作的,而HTTP属于它内部的一个子集
CP/IP是互联网相关的各类协议族的总称:
协议的作用
- 计算机与网络设备要相互通信,双方就必须基于相同的方法。比如,如何探测到通信目标、由哪一边先发起通信、使用哪种语言进行通信、怎样结束通信等规则都需要事先确定。不同的硬件、操作系统之间的通信,所有的这一切都需要一种规则。而我们就把这种规则称为协议(protocol)。
层次化的好处
把TCP/IP 层次化是有好处的。比如,如果互联网只由一个协议统筹,某个地方需要改变设计时,就必须把所有部分整体替换掉。而分层之后只需把变动的层替换掉即可。把各层之间的接口部分规划好之后每个层次内部的设计就能够自由改动了。值得一提的是,层次化之后,设计也变得相对简单了。处于应用层上的应用可以只考虑分派给自己的任务,而不需要弄清对方在地球上哪个地方、对方的传输路线是怎样的、是否能确保传输送达等问题。
应用层
- 应用层决定了向用户提供应用服务时通信的活动
- TCP/IP协议族内预存了各类通用的应用服务。比如,FTP(File TransferProtocol,文件传输协议)和DNS(Domain Name System,域名系统)服务就是其中两类。HTTP协议也处于该层。
传输层
- 传输层传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输
- 在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和UDP(User Data Protocol,用户数据报协议)。
网络层
- 网络层用来处理在网络上流动的数据包。数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。
- 与对方计算机之间通过多台计算机或网络设备进行传输时,网络层所起的作用就是在众多的选项内选择一条传输路线。
链路层(又名数据链路层,网络接口层)
- 用来处理连接网络的硬件部分
- 包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。硬件上的范畴均在链路层的作用范围之内。
数据传输流举例:
我们用HTTP举例来说明,首先作为发送端的客户端在应用层(HTTP协议)发出一个想看某个Web页面的HTTP请求。接着,为了传输方便,在传输层(TCP协议)把从应用层处收到的数据(HTTP请求报文)进行分割,并在各个报文上打上标记序号及端口号后转发给网络层。在网络层(IP协议),增加作为通信目的地的MAC地址后转发给链路层。这样一来,发往网络的通信请求就准备齐全了。接收端的服务器在链路层接收到数据,按序往上层发送,一直到应用层。当传输到应用层,才能算真正接收到由客户端发送过来的HTTP请求。
发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。
反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。
这种把数据信息包装起来的做法称为封装(encapsulate)。
与HTTP关系密切的协议:IP、TCP和DNS
负责传输的 IP 协议
可能有人会把“IP”和“IP地址”搞混,“IP”其实是一种协议的名称。
-
IP协议的作用是把各种数据包传送给对方。而要保证确实传送到对方那里,则需要满足各类条件。其中两个重要的条件是IP地址和MAC地址(Media AccessControl Address)
-
IP地址指明了节点被分配到的地址,MAC地址是指网卡所属的固定地址。IP地址可以和MAC地址进行配对。IP地址可变换,但MAC地址基本上不会更改
ARP协议作用
使用ARP协议凭借MAC地址进行通信IP间的通信依赖MAC地址。
- 在网络上,通信的双方在同一局域网(LAN)内的情况是很少的,通常是经过多台计算机和网络设备中转才能连接到对方。而在进行中转时,会利用下一站中转设备的MAC地址来搜索下一个中转目标。这时,会采用ARP协议(Address Resolution Protocol)。ARP是一种用以解析地址的协议,根据通信方的IP地址就可以反查出对应的MAC地址
没有人能够全面掌握互联网中的传输状况
- 在到达通信目标前的中转过程中,那些计算机和路由器等网络设备只能获悉很粗略的传输路线。这种机制称为路由选择(routing),有点像快递公司的送货过程。想要寄快递的人,只要将自己的货物送到集散中心,就可以知道快递公司是否肯收件发货,该快递公司的集散中心检查货物的送达地址,明确下站该送往哪个区域的集散中心。接着,那个区域的集散中心自会判断是否能送到对方的家中。我们是想通过这个比喻说明,无论哪台计算机、哪台网络设备,它们都无法全面掌握互联网中的细节。
确保可靠性的 TCP 协议
按层次分,TCP位于传输层,提供可靠的字节流服务。
- 所谓的字节流服务(Byte Stream Service)是指,为了方便传输,将大块数据分割成以报文段(segment)为单位的数据包进行管理。而可靠的传输服务是指,能够把数据准确可靠地传给对方。一言以蔽之,TCP协议为了更容易传送大数据才把数据分割,而且TCP协议能够确认数据最终是否送达到对方。为了准确无误地将数据送达目标处,TCP协议采用了三次握手(three-wayhandshaking)策略。
负责域名解析的 DNS 服务
DNS(Domain Name System)服务是和HTTP协议一样位于应用层的协议
它提供域名到IP地址之间的解析服务。计算机既可以被赋予IP地址,也可以被赋予主机名和域名。
在访问域名网页前会先由DNS服务器进行解析
三种协议与 HTTP 协议的关系
URI 和 URL
统一资源标识符 URI
URI就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。采用HTTP协议时,协议方案就是http。除此之外,还有ftp、mailto、telnet、file等。
URI 用字符串标识某一互联网资源,而URL表示资源的地点(互联网上所处的位置)。可见URL是URI的子集
URI格式
表示指定的URI,要使用涵盖全部必要信息的绝对URI、绝对URL以及相对URL。
相对URL,是指从浏览器中基本URI处指定的URL,形如 /image/logo.gif。
让我们先来了解一下绝对URI的格式。
使用http:或https:等协议方案名获取访问资源时要指定协议类型。不区分字母大小写,最后附一个冒号(:)。也可使用data:或javascript:这类指定数据或脚本程序的方案名。
- 登录信息(认证):指定用户名和密码作为从服务器端获取资源时必要的登录信息(身份认证)。此项是可选项。
- 服务器地址:使用绝对URI必须指定待访问的服务器地址。地址可以是类似hackr.jp这种DNS可解析的名称,或是192.168.1.1这类IPv4地址名,还可以是[0:0:0:0:0:0:0:1]这样用方括号括起来的IPv6地址名。
- 服务器端口号:指定服务器连接的网络端口号。此项也是可选项,若用户省略则自动使用默认端口号。
- 带层次的文件路径:指定服务器上的文件路径来定位特指的资源。这与UNIX系统的文件目录结构相似。
- 查询字符串:针对已指定的文件路径内的资源,可以使用查询字符串传入任意参数。此项可选。
- 片段标识符:使用片段标识符通常可标记出已获取资源中的子资源(文档内的某个位置)。但在RFC中并没有明确规定其使用方法。该项也为可选项。
统一资源定位符 URL
与URI(统一资源标识符)相比,我们更熟悉URL(Uniform Resource Locator,统一资源定位符)。
URL正是使用Web浏览器等访问Web页面时需要输入的网页地址。比如,下图的http://hackr.jp/就是URL。
第二章、简单的HTTP协议
了解客户端和服务器通讯的过程
HTTP协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应
请求报文
请求报文构成
响应报文
响应报文基本上由协议版本、状态码(表示请求成功或失败的数字代码)、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成
HTTP 是不保存状态的协议
HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信状态进行保存。也就是说在HTTP这个级别,协议对于发送过的请求或响应都不做持久化处理。
使用HTTP协议,每当有新的请求发送时,就会有对应的新响应产生。协议本身并不保留之前一切的请求或响应报文的信息。这是为了更快地处理大量事务,确保协议的可伸缩性,而特意把HTTP协议设计成如此简单的。
可是,随着Web的不断发展,因无状态而导致业务处理变得棘手的情况增多了。比如,用户登录到一家购物网站,即使他跳转到该站的其他页面后,也需要能继续保持登录状态。针对这个实例,网站为了能够掌握是谁送出的请求,需要保存用户的状态。HTTP/1.1虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了Cookie技术。有了Cookie再用HTTP协议通信,就可以管理状态了
请求 URI 定位资源
HTTP协议使用URI定位互联网上的资源。正是因为URI的特定功能,在互联网上任意位置的资源都能访问到。
当客户端请求访问资源而发送请求时,URI需要将作为请求报文中的请求URI包含在内。指定请求URI的方式有很多。
除此之外,如果不是访问特定资源而是对服务器本身发起请求,可以用一个*来代替请求URI。下面这个例子是查询HTTP服务器端支持的HTTP方法种类。
告知服务器意图的 HTTP 方法
GET :获取资源
GET方法用来请求访问已被URI识别的资源。指定的资源经服务器端解析后返回响应内容。也就是说,如果请求的资源是文本,那就保持原样返回;如果是像CGI(Common Gateway Interface,通用网关接口)那样的程序,则返回经过执行后的输出结果。
POST :传输实体主体
POST方法用来传输实体的主体。
虽然用GET方法也可以传输实体的主体,但一般不用GET方法进行传输,而是用POST方法。虽说POST的功能与GET很相似,但POST的主要目的并不是获取响应的主体内容。
PUT:传输文件
PUT方法用来传输文件。就像FTP协议的文件上传一样,要求在请求报文的主体中包含文件内容,然后保存到请求URI指定的位置。
但是,鉴于HTTP/1.1的PUT方法自身不带验证机制,任何人都可以上传文件,存在安全性问题,因此一般的Web网站不使用该方法。若配合Web应用程序的验证机制,或架构设计采用REST(Representational State Transfer,表征状态转移)标准的同类Web网站,就可能会开放使用PUT方法。
HEAD:获得报文首部
HEAD方法和GET方法一样,只是不返回报文主体部分。用于确认URI的有效性及资源更新的日期时间等。
DELETE:删除文件
DELETE方法用来删除文件,是与PUT相反的方法。
DELETE方法按请求URI删除指定的资源。但是,HTTP/1.1的DELETE方法本身和PUT方法一样不带验证机制,所以一般的Web网站也不使用DELETE方法。当配合Web应用程序的验证机制,或遵守REST标准时还是有可能会开放使用的。
OPTIONS:询问支持的方法
OPTIONS方法用来查询针对请求URI指定的资源支持的方法。
TRACE:追踪路径
TRACE 方法是让Web服务器端将之前的请求通信环回给客户端的方法。发送请求时,在Max-Forwards首部字段中填入数值,每经过一个服务器端就将该数字减1,当数值刚好减到0时,就停止继续传输,最后接收到请求的服务器端则返回状态码200 OK的响应。客户端通过TRACE方法可以查询发送出去的请求是怎样被加工修改/篡改的。这是因为,请求想要连接到源目标服务器可能会通过代理中转,TRACE方法就是用来确认连接过程中发生的一系列操作。
但是,TRACE方法本来就不怎么常用,再加上它容易引发XST(Cross-SiteTracing,跨站追踪)攻击,通常就更不会用到了。
CONNECT:要求用隧道协议连接代理
CONNECT方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行TCP通信。
主要使用SSL(Secure Sockets Layer,安全套接层)和TLS(TransportLayer Security,传输层安全)协议把通信内容加密后经网络隧道传输。
CONNECT方法的格式如下所示:
持久连接节省通信量
比如,使用浏览器浏览一个包含多张图片的HTML页面时,在发送请求访问HTML页面资源的同时,也会请求该HTML页面里包含的其他资源。因此,每次的请求都会造成无谓的TCP连接建立和断开,增加通信量的开销。
为解决上述TCP连接的问题,HTTP/1.1和一部分的HTTP/1.0想出了持久连接(HTTP Persistent Connections,也称为HTTP keep-alive或HTTP connectionreuse)的方法。
持久连接的特点是,只要任意一端没有明确提出断开连接,则保持TCP连接状态
持久连接的好处在于减少了TCP连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使HTTP请求和响应能够更早地结束,这样Web页面的显示速度也就相应提高了。**在HTTP/1.1中,所有的连接默认都是持久连接,但在HTTP/1.0内并未标准化。**虽然有一部分服务器通过非标准的手段实现了持久连接,但服务器端不一定能够支持持久连接。毫无疑问,除了服务器端,客户端也需要支持持久连接。
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了
使用 Cookie 的状态管理
HTTP是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
假设要求登录认证的Web页面本身无法进行状态的管理(不记录已登录的状态),那么每次跳转新页面就要再次登录,或者要在每次请求报文中附加参数来管理登录状态。
保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了Cookie技术。
Cookie技术通过在请求和响应报文中写入Cookie信息来控制客户端的状态。**Cookie会根据从服务器端发送的响应报文内的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。**当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入Cookie值后发送出去。服务器端发现客户端发送过来的Cookie后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
上图展示了发生Cookie交互的情景,HTTP请求报文和响应报文的内容如下。
第三章、HTTP报文内的HTTP信息
http报文
用于HTTP协议交互的信息被称为HTTP报文
请求端(客户端)的HTTP报文叫做请求报文,响应端(服务器端)的叫做响应报文。HTTP报文本身是由多行(用CR+LF作换行符)数据构成的字符串文本。
报文结构
请求报文与响应报文
- 求行包含用于请求的方法,请求URI和HTTP版本。
- 状态行包含表明响应结果的状态码,原因短语和HTTP版本。
- 首部字段包含表示请求和响应的各种条件和属性的各类首部。
- 一般有4种首部,分别是:通用首部、请求首部、响应首部和实体首部。
- 其他可能包含HTTP的RFC里未定义的首部(Cookie等)。
编码提升传输效率
HTTP在传输数据时可以按照数据原貌直接传输,但也可以在传输过程中通过编码提升传输速率。通过在传输时编码,能有效地处理大量的访问请求。但是,编码的操作需要计算机来完成,因此会消耗更多的CPU等资源。
报文主体与实体主体的差异
- 报文(message):是HTTP通信中的基本单位,由8位组字节流(octet sequence,其中octet为8个比特)组成,通过HTTP通信传输。
- 实体(entity):作为请求或响应的有效载荷数据(补充项)被传输,其内容由实体首部和实体主体组成。
HTTP报文的主体用于传输请求或响应的实体主体。通常,报文主体等于实体主体。只有当传输中进行编码操作时,实体主体的内容发生变化,才导致它和报文主体产生差异。报文和实体这两个术语在之后会经常出现,请事先理解两者的差异。
压缩传输的内容编码
向待发送邮件内增加附件时,为了使邮件容量变小,我们会先用ZIP压缩文件之后再添加附件发送。HTTP协议中有一种被称为内容编码的功能也能进行类似的操作。
内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。内容编码后的实体由客户端接收并负责解码。
常用的内容编码有以下几种。
- gzip(GNU zip)
- compress(UNIX系统的标准压缩)
- deflate(zlib)
- identity(不进行编码)
分割发送的分块传输编码
在HTTP通信过程中,请求的编码实体资源尚未全部传输完成之前,浏览器无法显示请求页面。在传输大容量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。
这种把实体主体分块的功能称为分块传输编码(Chunked Transfer Coding)
分块传输编码会将实体主体分成多个部分(块)。每一块都会用十六进制来标记块的大小,而实体主体的最后一块会使用“0(CR+LF)”来标记。
使用分块传输编码的实体主体会由接收的客户端负责解码,恢复到编码前的实体主体。HTTP/1.1中存在一种称为传输编码(Transfer Coding)的机制,它可以在通信时按某种编码方式传输,但只定义作用于分块传输编码中。
发送多种数据的多部分对象集合
发送邮件时,我们可以在邮件里写入文字并添加多份附件。这是因为采用了MIME(Multipurpose Internet Mail Extensions,多用途因特网邮件扩展)机制,它允许邮件处理文本、图片、视频等多个不同类型的数据
例如,图片等二进制数据以ASCII码字符串编码的方式指明,就是利用MIME来描述标记数据类型。而在MIME扩展中会使用一种称为多部分对象集合(Multipart)的方法,来容纳多份不同类型的数据。相应地,HTTP协议中也采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体。通常是在图片或文本文件等上传时使用。
相应地,HTTP协议中也采纳了多部分对象集合,发送的一份报文主体内可含有多类型实体。通常是在图片或文本文件等上传时使用。多部分对象集合包含的对象如下。
- multipart/form-data在Web表单文件上传时使用。
- multipart/byteranges状态码206(Partial Content,部分内容)响应报文包含了多个范围的内容时使用。
在HTTP报文中使用多部分对象集合时,需要在首部字段里加上Content-type。
使用boundary字符串来划分多部分对象集合指明的各类实体。在boundary字符串指定的各个实体的起始行之前插入“–”标记(例如:–AaB03x、–THIS_STRING_SEPARATES),而在多部分对象集合对应的字符串的最后插入“–”标记(例如:–AaB03x–、–THIS_STRING_SEPARATES–)作为结束。
多部分对象集合的每个部分类型中,都可以含有首部字段。另外,可以在某个部分中嵌套使用多部分对象集合。
获取部分内容的范围请求
以前,用户不能使用现在这种高速的带宽访问互联网,当时,下载一个尺寸稍大的图片或文件就已经很吃力了。如果下载过程中遇到网络中断的情况,那就必须重头开始。为了解决上述问题,需要一种可恢复的机制。所谓恢复是指能从之前下载中断处恢复下载
要实现该功能需要指定下载的实体范围。像这样,指定范围发送的请求叫做范围请求(Range Request)。对一份10000字节大小的资源,如果使用范围请求,可以只请求5001~10000字节内的资源。
执行范围请求时,会用到首部字段Range来指定资源的byte范围。byte范围的指定形式如下。
针对范围请求,响应会返回状态码为206 Partial Content的响应报文。另外,对于多重范围的范围请求,响应会在首部字段Content-Type标明multipart/byteranges后返回响应报文。
如果服务器端无法响应范围请求,则会返回状态码200 OK和完整的实体内容。
内容协商返回最合适的内容
同一个Web网站有可能存在着多份相同内容的页面。比如英语版和中文版的Web页面,它们内容上虽相同,但使用的语言却不同。当浏览器的默认语言为英语或中文,访问相同URI的Web页面时,则会显示对应的英语版或中文版的Web页面。这样的机制称为内容协商(ContentNegotiation)
内容协商机制是指客户端和服务器端就响应的资源内容进行交涉,然后提供给客户端最为适合的资源。内容协商会以响应资源的语言、字符集、编码方式等作为判断的基准。包含在请求报文中的某些首部字段(如下)就是判断的基准。
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
内容协商技术有以下3种类型:
- 服务器驱动协商(Server-driven Negotiation)由服务器端进行内容协商。以请求的首部字段为参考,在服务器端自动处理。但对用户来说,以浏览器发送的信息作为判定的依据,并不一定能筛选出最优内容。
- 客户端驱动协商(Agent-driven Negotiation)由客户端进行内容协商的方式。用户从浏览器显示的可选项列表中手动选择。还可以利用JavaScript脚本在Web页面上自动进行上述选择。比如按OS的类型或浏览器类型,自行切换成PC版页面或手机版页面。
- 透明协商(Transparent Negotiation)是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行内容协商的一种方法。
第四章、返回结果的http状态码
状态码告知从服务器端返回的请求结果
状态码的职责是当客户端向服务器端发送请求时,描述返回的请求结果。借助状态码,用户可以知道服务器端是正常处理了请求,还是出现了错误
数字中的第一位指定了响应类别,后两位无分类。响应类别有以下5种。
2XX 成功
2XX 的响应结果表明请求被正常处理了
1. 200 OK
表示从客户端发来的请求在服务器端被正常处理了。在响应报文内,随状态码一起返回的信息会因方法的不同而发生改变。比如,使用GET方法时,对应请求资源的实体会作为响应返回;而使用HEAD方法时,对应请求资源的实体主体不随报文首部作为响应返回(即在响应中只返回首部,不会返回实体的主体部分)。
2. 204 No Content
该状态码代表服务器接收的请求已成功处理,但在返回的响应报文中不含实体的主体部分。另外,也不允许返回任何实体的主体。比如,当从浏览器发出请求处理后,返回204响应,那么浏览器显示的页面不发生更新。
一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。
3. 206 Partial Content
该状态码表示客户端进行了范围请求,而服务器成功执行了这部分的GET请求。响应报文中包含由Content-Range指定范围的实体内容。
3XX 重定向
3XX 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求
1. 301 Moved Permanently
永久性重定向。该状态码表示请求的资源已被分配了新的URI,以后应使用资源现在所指的URI。也就是说,如果已经把资源对应的URI保存为书签了,这时应该按Location首部字段提示的URI重新保存。
2. 302 Found
临时性重定向。该状态码表示请求的资源已被分配了新的URI,希望用户(本次)能使用新的URI访问
和301 Moved Permanently状态码相似,但302状态码代表的资源不是被永久移动,只是临时性质的。换句话说,已移动的资源对应的URI将来还有可能发生改变。比如,用户把URI保存成书签,但不会像301状态码出现时那样去更新书签,而是仍旧保留返回302状态码的页面对应的URI。
3. 303 See Other
该状态码表示由于请求对应的资源存在着另一个URI,应使用GET方法定向获取请求的资源。
303状态码和302 Found状态码有着相同的功能,但303状态码明确表示客户端应当采用GET方法获取资源,这点与302状态码有区别。比如,当使用POST方法访问CGI程序,其执行后的处理结果是希望客户端能以GET方法重定向到另一个URI上去时,返回303状态码。虽然302 Found状态码也可以实现相同的功能,但这里使用303状态码是最理想的
当301、302、303响应状态码返回时,几乎所有的浏览器都会把POST改成GET,并删除请求报文内的主体,之后请求会自动再次发送。301、302标准是禁止将POST方法改变成GET方法的,但实际使用时大家都会这么做。
4. 304 Not Modified
该状态码表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回304 Not Modified(服务器端资源未改变,可直接使用客户端未过期的缓存)
304状态码返回时,不包含任何响应的主体部分。304虽然被划分在3XX类别中,但是和重定向没有关系。
5. 307 Temporary Redirect
临时重定向。该状态码与302 Found有着相同的含义。尽管302标准禁止POST变换成GET,但实际使用时大家并不遵守。
307会遵照浏览器标准,不会从POST变成GET。但是,对于处理响应时的行为,每种浏览器有可能出现不同的情况。
4XX 客户端错误
4XX的响应结果表明客户端是发生错误的原因所在
1. 400 Bad Request
该状态码表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。另外,浏览器会像200 OK一样对待该状态码。
2. 401 Unauthorized
该状态码表示发送的请求需要有通过HTTP认证(BASIC认证、DIGEST认证)的认证信息。另外若之前已进行过1次请求,则表示用户认证失败
返回含有401的响应必须包含一个适用于被请求资源的WWW-Authenticate首部用以质询(challenge)用户信息。当浏览器初次接收到401响应,会弹出认证用的对话窗口。
3. 403 Forbidden
该状态码表明对请求资源的访问被服务器拒绝了。服务器端没有必要给出拒绝的详细理由,但如果想作说明的话,可以在实体的主体部分对原因进行描述,这样就能让用户看到了。
未获得文件系统的访问授权,访问权限出现某些问题(从未授权的发送源IP地址试图访问)等列举的情况都可能是发生403的原因
4. 404 Not Found
该状态码表明服务器上无法找到请求的资源。除此之外,也可以在服务器端拒绝请求且不想说明理由时使用
5XX 服务器错误
5XX的响应结果表明服务器本身发生错误。
1. 500 Internal Server Error
该状态码表明服务器端在执行请求时发生了错误。也有可能是Web应用存在的bug或某些临时的故障
2. 503 Service Unavailable
该状态码表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。如果事先得知解除以上状况需要的时间,最好写入Retry-After首部字段再返回给客户端。
状态码和状况的不一致
不少返回的状态码响应都是错误的,但是用户可能察觉不到这点。比如Web应用程序内部发生错误,状态码依然返回200 OK,这种情况也经常遇到
第五章、与HTTP协作的web服务器
一台 Web 服务器可搭建多个独立域名的 Web 网址,也可作为通信路径上的中转服务器提升传输效率。
用单台虚拟主机实现多个域名
HTTP/1.1规范允许一台HTTP服务器搭建多个Web站点。比如,提供Web托管服务(Web Hosting Service)的供应商,可以用一台服务器为多位客户服务,也可以以每位客户持有的域名运行各自不同的网站。这是因为利用了虚拟主机(Virtual Host,又称虚拟服务器)的功能。
即使物理层面只有一台服务器,但只要使用虚拟主机的功能,则可以假想已具有多台服务器。
在相同的IP地址下,由于虚拟主机可以寄存多个不同主机名和域名的Web网站,因此在发送HTTP请求时,必须在Host首部内完整指定主机名或域名的URI。
通信数据转发程序:代理、网关、隧道
HTTP 通信时,除客户端和服务器以外,还有一些用于通信数据转发的应用程序,例如代理、网关和隧道。它们可以配合服务器工作。
这些应用程序和服务器可以将请求转发给通信线路上的下一站服务器,并且能接收从那台服务器发送的响应再转发给客户端。
- 代理
代理是一种有转发功能的应用程序,它扮演了位于服务器和客户端“中间人”的角色,接收由客户端发送的请求并转发给服务器,同时也接收服务器返回的响应并转发给客户端。 - 网关
网关是转发其他服务器通信数据的服务器,接收从客户端发送来的请求时,它就像自己拥有资源的源服务器一样对请求进行处理。有时客户端可能都不会察觉,自己的通信目标是一个网关。 - 隧道
隧道是在相隔甚远的客户端和服务器两者之间进行中转,并保持双方通信连接的应用程序
1. 代理
代理服务器的基本行为就是接收客户端发送的请求后转发给其他服务器。代理不改变请求URI,会直接发送给前方持有资源的目标服务器。
持有资源实体的服务器被称为源服务器。从源服务器返回的响应经过代理服务器后再传给客户端。
每次通过代理服务器转发请求或响应时,会追加写入Via首部信息
使用代理服务器的理由
使用代理服务器的理由有:利用缓存技术(稍后讲解)减少网络带宽的流量,组织内部针对特定网站的访问控制,以获取访问日志为主要目的,等等。
代理有多种使用方法,按两种基准分类。一种是是否使用缓存,另一种是是否会修改报文。
-
缓存代理
代理转发响应时,缓存代理(Caching Proxy)会预先将资源的副本(缓存)保存在代理服务器上。
当代理再次接收到对相同资源的请求时,就可以不从源服务器那里获取资源,而是将之前缓存的资源作为响应返回。 -
透明代理
转发请求或响应时,不对报文做任何加工的代理类型被称为透明代理(Transparent Proxy)。反之,对报文内容进行加工的代理被称为非透明代理。
2. 网关
利用网关可以由HTTP请求转化为其他协议通信
网关的工作机制和代理十分相似。而网关能使通信线路上的服务器提供非HTTP协议服务。
利用网关能提高通信的安全性,因为可以在客户端与网关之间的通信线路上加密以确保连接的安全。比如,网关可以连接数据库,使用SQL语句查询数据。另外,在Web购物网站上进行信用卡结算时,网关可以和信用卡结算系统联动。
3. 隧道
隧道可按要求建立起一条与其他服务器的通信线路,届时使用SSL等加密手段进行通信。隧道的目的是确保客户端能与服务器进行安全的通信。
隧道本身不会去解析HTTP请求。也就是说,请求保持原样中转给之后的服务器。隧道会在通信双方断开连接时结束。
通过隧道的传输,可以和远距离的服务器安全通信。隧道本身是透明的,客户端不用在意隧道的存在
保存资源的缓存
缓存是指代理服务器或客户端本地磁盘内保存的资源副本。利用缓存可减少对源服务器的访问,因此也就节省了通信流量和通信时间。
缓存服务器是代理服务器的一种,并归类在缓存代理类型中。换句话说,当代理转发从服务器返回的响应时,代理服务器将会保存一份资源的副本。
缓存服务器的优势在于利用缓存可避免多次从源服务器转发资源。因此客户端可就近从缓存服务器上获取资源,而源服务器也不必多次处理相同的请求了。
1. 缓存的有效期限
即便缓存服务器内有缓存,也不能保证每次都会返回对同资源的请求。因为这关系到被缓存资源的有效性问题。
当遇上源服务器上的资源更新时,如果还是使用不变的缓存,那就会演变成返回更新前的“旧”资源了。
即使存在缓存,也会因为客户端的要求、缓存的有效期等因素,向源服务器确认资源的有效性。若判断缓存失效,缓存服务器将会再次从源服务器上获取“新”资源。
2. 客户端的缓存
缓存不仅可以存在于缓存服务器内,还可以存在客户端浏览器中。以Internet Explorer程序为例,把客户端缓存称为临时网络文件(Temporary Internet File)。
浏览器缓存如果有效,就不必再向服务器请求相同的资源了,可以直接从本地磁盘内读取。
另外,和缓存服务器相同的一点是,当判定缓存过期后,会向源服务器确认资源的有效性。若判断浏览器缓存失效,浏览器会再次请求新资源。
第六章、HTTP首部
HTTP 报文首部
HTTP请求报文:在请求中,HTTP报文由方法、URI、HTTP版本、HTTP首部字段等部分构成。
HTTP响应报文:在响应中,HTTP报文由HTTP版本、状态码(数字和原因短语)、HTTP首部字段3部分构成。
HTTP 首部字段
HTTP首部字段传递重要信息
HTTP首部字段是构成HTTP报文的要素之一。在客户端与服务器之间以HTTP协议进行通信的过程中,无论是请求还是响应都会使用首部字段,它能起到传递额外重要信息的作用。
使用首部字段是为了给浏览器和服务器提供报文主体大小、所使用的语言、认证信息等内容。
4 种 HTTP 首部字段类型
HTTP首部字段根据实际用途被分为以下4种类型。
- 通用首部字段(General Header Fields)
请求报文和响应报文两方都会使用的首部。 - 请求首部字段(Request Header Fields)
从客户端向服务器端发送请求报文时使用的首部。补充了请求的附加内容、客户端信息、响应内容相关优先级等信息。 - 响应首部字段(Response Header Fields)
从服务器端向客户端返回响应报文时使用的首部。补充了响应的附加内容,也会要求客户端附加额外的内容信息。 - 实体首部字段(Entity Header Fields)
针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
非HTTP/1.1首部字段
在HTTP协议通信交互中使用到的首部字段,不限于RFC2616中定义的47种首部字段。还有Cookie、Set-Cookie和Content-Disposition等在其他RFC中定义的首部字段,它们的使用频率也很高。
这些非正式的首部字段统一归纳在RFC4229 HTTP Header FieldRegistrations中。
End-to-end首部和Hop-by-hop首部
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
为Cookie服务的首部字段
管理服务器与客户端之间状态的Cookie,虽然没有被编入标准化HTTP/1.1的RFC2616中,但在Web网站方面得到了广泛的应用。
Cookie的工作机制是用户识别及状态管理。Web网站为了管理用户的状态会通过Web浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该Web网站时,可通过通信方式取回之前存放的Cookie。
调用Cookie时,由于可校验Cookie的有效期,以及发送方的域、路径、协议等信息,所以正规发布的Cookie内的数据不会因来自其他Web站点和攻击者的攻击而泄露。
Set-Cookie与Cookie
第七章、确保web安全的htttps
htttp缺点:
- 通信使用明文(不加密),内容可能会被窃听
- 不验证通信方的身份,因此有可能遭遇伪装
- 无法证明报文的完整性,所以有可能已遭篡改
抓包工具
通信加密
HTTP可以通过和SSL(安全套接层)或TLS(安全层传输协议)的组合使用,加密HTTP的通信内容。
用SSL建立安全通信线路后,就可以在这条线路上进行HTTP通信。与SSL组合使用的HTTP称为HTTPS
缺点:无法证明报文的完整性,所以有可能已遭篡改
内容加密
由于HTTP协议中没有加密机制,那么就对HTTP协议传输的内容本身加密。
即把HTTP报文例所含的内容加密处理。
查明对手的证书
SSL不仅提供加密处理,而且使用了一种被称为证书的手段,可以用于确定方的证书是由值得信任的第三方机构颁发,用以证明服务器和客户端是实际存在的。
HTTPS(=HTTP+加密+认证+完整性保护)
HTTPS并非是应用层的一种新协议,只是HTTP通信接口部分用SSL和TLS协议代替了而已。
通常,HTTP直接和TCP通信。当使用SSL时,则演变成先和SSL通信,再有SSL和TCP通信。
所以HTTPS就是身披SSL协议这层外壳的HTTP。
在采用SSL后,HTTP就拥有了HTTPS加密、证书和完整性保护等功能。
SSL是独立于HTTP的协议,所以不光是HTTP协议,其他运行在应用层的SMTP和Telent等协议均可配合SSL协议使用。
SSL是当今世界上应用最为广泛的网络安全技术。
公开秘钥加密方法
SSL采用公开秘钥加密的处理方式,公开秘钥加密解决了共享秘钥加密的困难
公开秘钥加密使用一对非对称秘钥。一把叫做私有秘钥,另一把叫做公开秘钥。
私有秘钥不能让其他任何人知道,而公开秘钥可以随意发布,任何人都可以获得。
使用公开密钥加密方式,发送密文的一方使用对方的公开密钥进行加密处理,对方收到被加密的信息后,再使用自己的私有秘钥进行解密。利用这种方式,不需要发送用来解密的私有密钥,也不必担心密钥被攻击者窃听而盗走。
另外,要想根据密文和公开秘钥,恢复到信息原文是异常困难的。
HTTPS采用混合加密机制
HTTPS采用共享秘钥加密和公开秘钥加密两者并用的混合加密机制。
在交换密钥环节使用公开密钥加密方式,之后的建立通信交换报文阶段则使用共享密钥加密方式。
证明公开秘钥正确性的证书
公开密钥加密方式存在的问题:无法证明公开密钥本身是真的公开密钥。
公开密钥传输途中,可能被攻击者替换掉了。
为了解决上述问题,可以使用由数字证书认证机构和其他相关机构颁发的公开密钥证书。
所以,服务器发送给客户端的是服务器的公开秘钥和数字证书(公钥证书),不只是证书,客户端拿到正确的公开秘钥就可以将自己的私钥进行加密然后发送给服务器
用以确认客户端的客户端证书
HTTPS的安全通信机制
HTTPS通信步骤:
SSL与TLS
第八章、确认访问用户身份的认证
某些 Web 页面只想让特定的人浏览,或者干脆仅本人可见。为达到这个目标,必不可少的就是认证功能。
何为认证
计算机本身无法判断坐在显示器前的使用者的身份。进一步说,也无法确认网络的那头究竟有谁。为了弄清究竟是谁在访问服务 器,就得让对方的客户端自报家门。核对的信息通常是指以下这些。
- 密码:只有本人才会知道的字符串信息。
- 动态令牌:仅限本人持有的设备内显示的一次性密码。
- 数字证书:仅限本人(终端)持有的信息。
- 生物认证:指纹和虹膜等本人的生理信息。
- IC 卡等:仅限本人持有的信息。
HTTP 使用的认证方式 HTTP/1.1 使用的认证方式如下所示。
- BASIC 认证(基本认证)
- DIGEST 认证(摘要认证)
- SSL 客户端认证
- FormBase 认证(基于表单认证)
基于表单认证
认证多半基于表单认证:DIGEST和BASIC认证几乎不使用,SSL客户端认证代价太高,尚未普及。SSH和FTP协议合乎标准并且满足安全使用级别,因此这些协议的认证可以直接拿来使用。
客户端会向服务器上的web应用程序发送登录信息,按登录信息的验证结果认证。多数情况下,输入已事先登录的用户 ID(通常是任意字符串或邮件 地址)和密码等登录信息后,发送给 Web 应用程序,基于认证结果 来决定认证是否成功。
Session 管理及 Cookie 应用
基于表单认证本身是通过服务器端的 Web 应用,将客户端发送过来 的用户 ID 和密码与之前登录过的信息做匹配来进行认证的。 但鉴于 HTTP 是无状态协议,之前已认证成功的用户状态无法通过协 议层面保存下来。即无法实现状态管理,因此即使当该用户下一次 继续访问,也无法区分他与其他的用户。于是我们会使用 Cookie 来 管理 Session,以弥补 HTTP 协议中不存在的状态管理功能。
基于http的功能追加协议
使用浏览器进行全双工通信的websocket
利用 Ajax 和 Comet 技术进行通信可以提升 Web 的浏览速度。但问题在于通信若使用 HTTP 协议,就无法彻底解决瓶颈问题。WebSocket网络技术正是为解决这些问题而实现的一套新协议及 API。
一旦 Web 服务器与客户端之间建立起 WebSocket 协议的通信连接,之后所有的通信都依靠这个专用协议进行。通信过程中可互相发送JSON、XML、HTML 或图片等任意格式的数据。由于是建立在 HTTP 基础上的协议,因此连接的发起方仍是客户端,而一旦确立 WebSocket 通信连接,不论服务器还是客户端,任意一方都可直接向对方发送报文。
WebSocket 协议的主要特点
- 推送功能支持由服务器向客户端推送数据的推送功能:这样,服务器可直接发送数据,而不必等待客户端的请求
- 减少通信量:只要建立起 WebSocket 连接,就希望一直保持连接状态。和 HTTP相比,不但每次连接时的总开销减少,而且由于 WebSocket 的首部信息很小,通信量也相应减少了。为了实现 WebSocket 通信,在 HTTP 连接建立之后,需要完成一次“握手”(Handshaking)的步骤
握手·请求
握手·响应
成功握手确立WebSocket 连接之后,通信时不再使用HTTP的数据帧、而采用 WebSocket 独立的数据顿。
关于websocket的API
参考博文:
图解HTTP