目录
第 1 章 了解 Web 及网络基础
1.1 使用 HTTP 协议访问 Web
Web 使用一种名为HTTP(HyperText Transfer Protocol,超文本传输协议 )的协议作为规范,完成从客户端到服务器端等一系列运作流程。而协议是指规则的约定。可以说,Web 是建立在 HTTP 协议上通信的。
1.2 HTTP 的诞生
- HTTP/0.9
HTTP 于 1990 年问世。那时的 HTTP 并没有作为正式的标准被建立。现在的 HTTP 其实含有 HTTP1.0 之前版本的意思,因此被称为 HTTP/0.9。
- HTTP/1.0
HTTP 正式作为标准被公布是在 1996 年的 5 月,版本被命名为 HTTP/1.0,并记载于 RFC1945。虽说是初期标准,但该协议标准至今仍被广泛使用在服务器端。
1997 年 1 月公布的 HTTP/1.1 是目前主流的 HTTP 协议版本。当初的标准是 RFC2068,之后发布的修订版 RFC2616 就是当前的最新版本。
1.3 网络基础 TCP/IP
1.3.1 TCP/IP 协议族
像这样把与互联网相关联的协议集合起来总称为 TCP/IP。也有说法认为,TCP/IP 是指 TCP 和 IP 这两种协议。还有一种说法认为,TCP/ IP 是在 IP 协议的通信过程中,使用到的协议族的统称。
1.3.2 TCP/IP 的分层管理
TCP/IP 协议族里重要的一点就是分层。TCP/IP 协议族按层次分别分为以下 4 层:应用层、传输层、网络层和数据链路层。
把 TCP/IP 层次化是有好处的。比如,如果互联网只由一个协议统筹,某个地方需要改变设计时,就必须把所有部分整体替换掉。而分层之后只需把变动的层替换掉即可。把各层之间的接口部分规划好之后,每个层次内部的设计就能够自由改动了。
- 应用层:决定了向用户提供应用服务时通信的活动。
TCP/IP 协议族内预存了各类通用的应用服务。比如,FTP(File Transfer Protocol,文件传输协议)和 DNS(Domain Name System,域名系统)服务就是其中两类。
HTTP 协议也处于该层。
- 传输层:对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。
在传输层有两个性质不同的协议:TCP(Transmission Control Protocol,传输控制协议)和 UDP(User Data Protocol,用户数据报协议)。
- 网络层(又名网络互连层):用来处理在网络上流动的数据包。
数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。
数据包是网络传输的最小数据单位。该层规定了通过怎样的路径(所谓的传输路线)到达对方计算机,并把数据包传送给对方。
- 链路层(又名数据链路层、网络接口层):用来处理连接网络的硬件部分。
包括控制操作系统、硬件的设备驱动、NIC(Network Interface Card,网络适配器,即网卡),及光纤等物理可见部分(还包括连接器等一切传输媒介)。
硬件上的范畴均在链路层的作用范围之内。
1.3.3 TCP/IP 通信传输流
发送端在层与层之间传输数据时,每经过一层时必定会被打上一个该层所属的首部信息。反之,接收端在层与层传输数据时,每经过一层时会把对应的首部消去。这种把数据信息包装起来的做法称为封装(encapsulate)。
1.4 与 HTTP 关系密切的协议 : IP、TCP 和 DNS
1.4.1 负责传输的 IP 协议
- 按层次分,IP(Internet Protocol)网际协议位于网络层
- 几乎所有使用网络的系统都会用到 IP 协议
- TCP/IP 协议族中的 IP 指的就是网际协议
IP 协议的作用是把各种数据包传送给对方。而要保证确实传送到对方那里,则需要满足各类条件。其中两个重要的条件是 IP 地址和 MAC 地址(Media Access Control Address)。
IP 地址指明了节点被分配到的地址,MAC 地址是指网卡所属的固定地址。IP 地址可以和 MAC 地址进行配对。IP 地址可变换,但 MAC 地址基本上不会更改。
使用 ARP 协议凭借 MAC 地址进行通信
IP 间的通信依赖 MAC 地址。在网络上,通信的双方在同一局域网(LAN)内的情况是很少的,通常是经过多台计算机和网络设备中转才能连接到对方。而在进行中转时,会利用下一站中转设备的 MAC 地址来搜索下一个中转目标。这时,会采用 ARP 协议(Address Resolution Protocol)。ARP 是一种用以解析地址的协议,根据通信方的 IP 地址就可以反查出对应的 MAC 地址。
1.4.2 确保可靠性的 TCP 协议
- 按层次分,TCP 位于传输层,提供可靠的字节流服务
所谓的字节流服务(Byte Stream Service)是指,为了方便传输,将大块数据分割成以报文段(segment)为单位的数据包进行管理。
而可靠的传输服务是指,能够把数据准确可靠地传给对方。
一言以蔽之,TCP 协议为了更容易传送大数据才把数据分割,而且 TCP 协议能够确认数据最终是否送达到对方。
确保数据能到达目标
- TCP 协议采用了三次握手(three-way handshaking)策略
- 握手过程中使用了 TCP 的标志(flag) —— SYN(synchronize) 和 ACK(acknowledgement)
发送端首先发送一个带 SYN 标志的数据包给对方。接收端收到后,回传一个带有 SYN/ACK 标志的数据包以示传达确认信息。最后,发送端再回传一个带 ACK 标志的数据包,代表“握手”结束。
若在握手过程中某个阶段莫名中断,TCP 协议会再次以相同的顺序发送相同的数据包。
1.5 负责域名解析的 DNS 服务
- DNS(Domain Name System)服务和 HTTP 协议一样位于应用层
- 提供域名到 IP 地址之间的解析服务
1.6 各种协议与 HTTP 协议的关系
- DNS 服务:解析域名至对应的IP地址
- HTTP 协议:生成针对目标Web服务器的HTTP请求报文
- TCP 协议:将请求报文按序号分割成多个报文段
- IP 协议:搜索对方的地址,一边中转一边传送
- TCP 协议:按序号以原来的顺序重组请求报文
- 请求的处理结果也同样利用TCP/IP协议向用户进行回传
1.7 URI 和 URL
- URI(Uniform Resource Identifier):统一资源标识符
- URL(Uniform Resource Locator):统一资源定位符
1.7.1 统一资源标识符
URI 是 Uniform Resource Identifier 的缩写,RFC2396 分别对这 3 个单词进行了如下定义。
- Uniform
规定统一的格式可方便处理多种不同类型的资源,而不用根据上下文环境来识别资源指定的访问方式。
另外,加入新增的协议方案(如 http: 或 ftp:)也更容易。
- Resource
资源的定义是“可标识的任何东西”。除了文档文件、图像或服务(例如当天的天气预报)等能够区别于其他类型的,全都可作为资源。
另外,资源不仅可以是单一的,也可以是多数的集合体。
- Identifier
表示可标识的对象。也称为标识符。
综上所述,URI 就是由某个协议方案表示的资源的定位标识符。协议方案是指访问资源所使用的协议类型名称。
“RFC3986:统一资源标识符(URI)通用语法”中列举了几种 URI 例子,如下所示。
ftp://ftp.is.co.za/rfc/rfc1808.txt
http://www.ietf.org/rfc/rfc2396.txt
ldap://[2001:db8::7]/c=GB?objectClass?one
mailto:John.Doe@example.com
news:comp.infosystems.www.servers.unix
tel:+1-816-555-1212
telnet://192.0.2.16:80/
urn:oasis:names:specification:docbook:dtd:xml:4.1.2
1.7.2 URI 格式
表示指定的 URI,要使用涵盖全部必要信息的绝对 URI、绝对 URL 以及相对 URL。相对 URL,是指从浏览器中基本 URI 处指定的 URL,形如 /image/logo.gif
。
- 登陆信息(认证)
指定用户名和密码作为从服务器端获取资源时必要的登录信息(身份认证)。此项是可选项。
- 服务器地址
使用绝对 URI 必须指定待访问的服务器地址。地址可以是类似 hackr.jp 这种 DNS 可解析的域名,或是 192.168.1.1 这类 IPv4 地址 名,还可以是 [0:0:0:0:0:0:0:1] 这样用方括号括起来的 IPv6 地址名。
- 服务器端口号
指定服务器连接的网络端口号。此项也是可选项,若用户省略则自动使用默认端口号。
- 带层次的文件路径
指定服务器上的文件路径来定位特指的资源。这与 UNIX 系统的文件目录结构相似。
- 查询字符串
针对已指定的文件路径内的资源,可以使用查询字符串传入任意参数。此项可选。
- 片段标识符
使用片段标识符通常可标记出已获取资源中的子资源(文档内的某个位置)。但在 RFC 中并没有明确规定其使用方法。该项也为可选项。
第 2 章 简单的 HTTP 协议
2.1 HTTP 协议用于客户端和服务器端之间的通信
请求访问文本或图像等资源的一端称为客户端,而提供资源响应的一端称为服务器端。
在两台计算机之间使用 HTTP 协议通信时,在一条通信线路上必定有一端是客户端,另一端则是服务器端。
有时候,按实际情况,两台计算机作为客户端和服务器端的角色有可能会互换。但就仅从一条通信路线来说,服务器端和客户端的角色是确定的,而用 HTTP 协议能够明确区分哪端是客户端,哪端是服务器端。
2.2 通过请求和相应的交换达成通信
HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
下面是从客户端发送给某个 HTTP 服务器端的请求报文中的内容。
GET /index.htm HTTP/1.1
Host: hackr.jp
- GET 表示请求访问服务器的类型,称为方法(method)
/index.htm
指明了请求访问的资源对象,称为请求URI(request-URI)- HTTP/1.1 表示HTTP的版本号,用来提示客户端使用的 HTTP 协议功能
综合来看,这段请求内容的意思是:请求访问某台 HTTP 服务器上的 /index.htm 页面资源。
请求报文是由请求方法、请求 URI、协议版本、可选的请求首部字段和内容实体构成的。
接收到请求的服务器,会将请求内容的处理结果以响应的形式返回。
HTTP/1.1 200 OK
Date: Tue, 10 Jul 2012 06:50:15 GMT
Content-Length: 362
Content-Type: text/html
<html>
……
- HTTP/1.1 表示服务器对应的HTTP版本
- 200 OK 表示请求的处理结果的状态码(status code)和原因短语(reason-phrase)
- Date 是首部字段(header filed)内的一个属性
- 之后的内容称为资源实体的主体(entity body)
响应报文基本上由协议版本、状态码、用以解释状态码的原因短语、可选的响应首部字段以及实体主体构成。
2.3 HTTP 是不保存状态的协议
HTTP 是一种不保存状态,即无状态(stateless)协议。HTTP 协议自身不对请求和响应之间的通信状态进行保存。也就是说在 HTTP 这个级别,协议对于发送过的请求或响应都不做持久化处理。
HTTP/1.1 虽然是无状态协议,但为了实现期望的保持状态功能,于是引入了 Cookie 技术。有了 Cookie 再用 HTTP 协议通信,就可以管理状态了。
2.4 请求 URI 定位资源
HTTP 协议使用 URI 定位互联网上的资源。正是因为 URI 的特定功能,在互联网上任意位置的资源都能访问到。
当客户端请求访问资源而发送请求时,URI 需要将作为请求报文中的请求 URI 包含在内。指定请求 URI 的方式有很多。
除此之外,如果不是访问特定资源而是对服务器本身发起请求,可以用一个 *
来代替请求 URI。下面这个例子是查询 HTTP 服务器端支持 的 HTTP 方法种类。
OPTIONS * HTTP/1.1
2.5 告知服务器意图的 HTTP 方法
下面介绍 HTTP/1.1 中可使用的方法。
- GET:获取资源
GET 方法用来请求访问已被 URI 识别的资源,指定的资源经服务器端解析后返回响应内容。
- 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-Site Tracing,跨站追踪)攻击,通常就更不会用到了。
- CONNECT:要求用隧道协议连接代理
CONNECT 方法要求在与代理服务器通信时建立隧道,实现用隧道协议进行 TCP 通信。主要使用 SSL(Secure Sockets Layer,安全套接层)和 TLS(Transport Layer Security,传输层安全)协议把通信内容加 密后经网络隧道传输。
2.6 使用方法下达命令
向请求 URI 指定的资源发送请求报文时,采用称为方法的命令。
方法的作用在于,可以指定请求的资源按期望产生某种行为。方法中有 GET、POST 和 HEAD 等。
下表列出了 HTTP/1.0 和 HTTP/1.1 支持的方法。另外,方法名区分大小写,注意要用大写字母。
方法 | 说明 | 支持的 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.1 |
UNLINE | 断开连接关系 | 1.1 |
LINK 和 UNLINK 已被 HTTP/1.1 废弃,不再支持。
2.7 持久连接节省通信量
HTTP 协议的初始版本中,每进行一次 HTTP 通信就要断开一次 TCP 连接。
以当年的通信情况来说,因为都是些容量很小的文本传输,所以即使这样也没有多大问题。可随着 HTTP 的普及,文档中包含大量图片的情况多了起来。
比如,使用浏览器浏览一个包含多张图片的 HTML 页面时,在发送请求访问 HTML 页面资源的同时,也会请求该 HTML 页面里包含的其他资源。因此,每次的请求都会造成无谓的 TCP 连接建立和断开,增加通信量的开销。
2.7.1 持久连接
为解决上述 TCP 连接的问题,HTTP/1.1 和一部分的 HTTP/1.0 想出了持久连接(HTTP Persistent Connections,也称为 HTTP keep-alive 或 HTTP connection reuse)的方法。持久连接的特点是,只要任意一端没有明确提出断开连接,则保持 TCP 连接状态。
持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使 HTTP 请求和响应能够更早地结束,这样 Web 页面的显示速度也就相应提高了。
2.7.2 管线化
持久连接使得多数请求以管线化(pipelining)方式发送成为可能。从前发送请求后需等待并收到响应,才能发送下一个请求。管线化技术出现后,不用等待响应亦可直接发送下一个请求。
这样就能够做到同时并行发送多个请求,而不需要一个接一个地等待响应了。
比如,当请求一个包含 10 张图片的 HTML Web 页面,与挨个连接相比,用持久连接可以让请求更快结束。而管线化技术则比持久连接还要快。请求数越多,时间差就越明显。
2.8 使用 Cookie 的状态管理
HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 Cookie 技术。Cookie 技术通过在请求和响应报文中写入 Cookie 信息来控制客户端的状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做
Set-Cookie
的首部字段信息,通知客户端保存 Cookie。当下次客户端再往该服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送出去。
服务器端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客户端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
在发生 Cookie 交互的场景中,HTTP 请求报文和响应报文的内容如下。
- 请求报文(没有 Cookie 信息的状态)
GET /reader/ HTTP/1.1
Host: hackr.jp
*首部字段内没有Cookie的相关信息
- 响应报文(服务器端生成 Cookie 信息)
HTTP/1.1 200 OK
Date: Thu, 12 Jul 2012 07:12:20 GMT
Server: Apache
<Set-Cookie: sid=1342077140226724; path=/; expires=Wed,
10-Oct-12 07:12:20 GMT>
Content-Type: text/plain; charset=UTF-8
- 请求报文(自动发送保存着的 Cookie 信息)
GET /image/ HTTP/1.1
Host: hackr.jp
Cookie: sid=1342077140226724