图解 http
第一章
- 通过发送请求获取服务器资源的 Web 浏览器等,都可以成为客户端(client)。
- web 使用一种名为 HTTP(HyperText Transfer Protocol 超文本传输协议)的协议作为规范。
- 通常使用的网络是在 TCP/IP 协议族的基础上运作的。而 HTTP 属于它内部的一个子集。
- 计算机与网络设备要相互通信,双方就必须基于相同的方法。不同的硬件、操作系统之间的通信,所有的这一切都需要一种规则。我们就把这种规则称为协议
protocol
- 像这样把与互联网关联的协议集合起来总称为
TCP/IP
。也有说法认为,TCP/IP
是指TCP
和IP
这两种协议。还有一种说法认为,TCP/IP
是在IP
协议的通信过程中,使用到的协议族的统称。 TCP/IP
协议族里重要的一点就是分层。TCP/IP
协议族按层次分别分为以下 4 层:应用层、传输层、网络层和数据链路层。- 把
TCP/IP
层次化是有好处的。比如,如果互联网只由一个协议统筹,某个地方需要改变设计时,就必须把所有部分整体替换掉。而分层之后只需把变动的层替换掉即可。把各层之间的接口部分规划好之后,每个层次内部的设计就能够自由改动了。(这段同写代码一样) - 层次化之后,设计也变得相对简单了。处于应用层上的应用可以只考虑分派给自己的任务,而不需要弄清对方在地球上哪个地方、对方的传输路线是怎样的、是否能够确保传输送达等问题。(这段同 MV*模式)
TCP/IP 协议族各层的作用:
- 应用层
- 应用层决定了向用户提供应用服务时通信的活动。如 FTP、DNS 等。HTTP 协议也处于该层。
- 传输层
- 传输层对上层应用层,提供处于网络连接中的两台计算机之间的数据传输。TCP
- 网络层
- 网络层用来处理在网络上流动的数据包。该层规定了通过怎样的路径到达对方计算机,并把数据包传送给对方。 与对方计算机之间通过多台计算机或网络设备传输时,网络层提供的作用就是在众多的选项内提供一条传输路线。IP
- 链路层
- 用来处理连接网络的硬件部分。网络
- 应用层
- 发送端在层与层传送数据时,会被打上该层所属的首部信息。接收端在层与层之间会把对应的首部消去。这种把数据信息包装起来的做法称为封装。
- TCP 协议采用了三次握手策略。发送端首先发送一个带有 SYN 标志的数据包给对方,接收端收到后,回传一个 SYN/ACK 标志的数据包以示传达确认信息。最后发送端再回传一个带 ACK 标志的数据包,代表握手结束。
- DNS(Domain Name System)提供域名到 IP 地址之间的解析服务。 一般用户都是通过域名来访问的,而不是通过 IP 地址来访问,因为记住一串数字比较难。但是让计算机去理解名称就比较困难了,所以 DNS 服务应运而生。通过域名来查找地址,然后反馈一个 IP 地址。 - 发送端输入网址 - DNS 返回一个 IP 地址 - 发送端用 IP 地址来进行访问。
- URI(统一资源标识符);URL(统一资源定位符);URI 用字符串标识某一互联网资源;URL 表示资源的地点;URL 是 URI 的子集;
第二章
HTTP 协议用于客户端和服务端之间的通信
HTTP 协议规定,请求从客户端发出,最后服务器端响应该请求并返回。换句话说,肯定是先从客户端开始建立通信的,服务器端在没有接收到请求之前不会发送响应。
方法:
| 方法名 | 含义 | | ------- | ---------------------- | | GET | 获取资源 | | POST | 传输实体主体 | | PUT | 用来传输文件 | | HEAD | 获得报文首部 | | DELETE | 删除文件 | | OPTIONS | 询问支持的方法 | | TRACE | 追踪路径 | | CONNECT | 要求用隧道协议连接代理 |
方法区分大小写,用大写来表示。
在 http 协议的初始版本里,每进行一次 HTTP 通信就要断开一次 TCP 连接;为了解决 TCP 连接的问题,有了持久连接(http keep-alive),也就是只要建立连接就能一次性发送请求的资源了;而管线化能做到同事并行发送多个请求,而不需要一个接一个地等待响应了,这样大大提高了效率。
持久连接的好处在于减少了 TCP 连接的重复建立和断开所造成的额外开销,减轻了服务器端的负载。另外,减少开销的那部分时间,使 HTTP 请求和响应能够更早的结束,这样 Web 页面的显示速度也就相应提高了。
在 HTTP/1.1 中,所有的连接默认都是持久连接。
HTTP 是无状态协议,它不对之前发生过的请求和响应的状态进行管理。不可否认,无状态协议当然有它的优点。由于不必保存状态,自然可减少服务器的 CPU 及内存资源的消耗。
保留无状态协议这个特征的同时又要解决类似的矛盾问题,于是引入了 cookie 技术。Cookie 技术通过在请求和响应报文中写入 cookie 信息来控制客户端的状态。
Cookie 会根据从服务器端发送的响应报文内的一个叫做 Set-Cookie 的首部字段信息,通知客户端保存 Cookie。当下次客户端再往服务器发送请求时,客户端会自动在请求报文中加入 Cookie 值后发送过去。
服务端发现客户端发送过来的 Cookie 后,会去检查究竟是从哪一个客服端发来的连接请求,然后对比服务器上的记录,最后得到之前的状态信息。
第三章
- 用于 HTTP 协议交互的信息被称为 HTTP 报文。
- 请求端的叫请求报文,响应端的叫响应报文。
- HTTP 报文大致可分为报文首部和报文主体两块。
- 内容编码指明应用在实体内容上的编码格式,并保持实体信息原样压缩。并由客户端负责接收和解码。
常见的内容编码有以下几种:
- gzip(GNU zip)
- compress(UNIX 系统的标准压缩)
- deflate(zlib)
- identity(不进行编码)
在 http 通信的过程中,请求的编码实体资源尚未全部传输完成之前,浏览器是无法显示请求页面的。在传输大量数据时,通过把数据分割成多块,能够让浏览器逐步显示页面。
- 分块传输编码是将实体分割成多个块。每一块都会用十六进制来标记块的大小。
- 以前用户不能通过现在这种高速的带宽访问互联网,下载图片资源很费劲,如果下载过程中遇到网络中断的情况,那就必须重头开始。为了解决这个问题,提供了一种恢复机制,即能从之前下载中断处恢复下载。
- 要实现上述功能需要指定下载的实体范围。指定范围发送的请求叫做范围请求(Range Request)
对一份 10000 字节大小的资源,如果使用范围请求,可以只请求 5001 ~ 10000 字节内的资源。
- Range: bytes=5001-1000 请求 5001-1000 字节
- Range: bytes=5001- 请求 5001 字节之后全部的
- Range: bytes=0-3000, 5000-7000 从一开始到 3000 字节和 5000-7000 字节的多重范围
针对范围请求会返回 206 的状态码。针对多重范围的范围请求,响应会在首部字段
Content-Type
标明multipart/byteranges
后返回响应报文。如果服务器无法响应范围请求,则会返回状态码 200 OK 和完整的实体内容。- 同一个 web 网站可能存在着多份相同的内容的页面,比如中文版和英文版的。当浏览器的默认语言为英语或中文,访问相同的 URI 的 web 页面时,则会显示对应语言的页面。这样的机制称为内容协商
Content Negotiation
。 内容协商指客户端和服务端根据响应的资源内容进行交涉,然后提供给最为合适的资源。内容协商会以语言、字符集、编码方式等为基准进行判断。
请求报文中的如下首部字段就是判断的基准。
- Accept
- Accept-Charset
- Accept-Encoding
- Accept-Language
- Content-Language
内容协商技术有以下 3 种类型:
- 服务器驱动协商(Server-driven Negotiation)
由服务器进行协商。以请求的首部字段作为参考,在服务器端自动处理。但对用户来说,以浏览器发送的信息作为判定的依据,并不能一定筛选出最优内容
- 客户端驱动协商(Agent-driven Negotiation)
由客户端进行协商。用户从浏览器显示的可选项列表中手动选择。还可以利用 JavaScript 脚本在 Web 页面上自动进行上述选择。比如按 OS 的类型或浏览器的类型,自动切换 PC 版页面或手机版页面。
- 透明协商(Transparent Negotiation)
是服务器驱动和客户端驱动的结合体,是由服务器端和客户端各自进行协商的一种办法。
第四章
状态码 2xx
200 OK
表示从客户端发来的请求在服务器端被正常处理了。如在使用 GET 请求时,对应请求资源的实体会作为响应返回。204 No Content
表示服务器接收的请求已成功处理,但在返回的响应报文中不包含实体的主体部分。另外,也不允许返回任何实体的主体。一般在只需要从客户端往服务器发送信息,而对客户端不需要发送新信息内容的情况下使用。206 Partial Content
表示客户端进行了范围请求,而服务器成功执行了这部分的 GET 请求。响应报文中包含有 Content-Range 指定范围的实体内容。
状态码 3xx。3xx 响应结果表明浏览器需要执行某些特殊的处理以正确处理请求。
301 Moved Permanently
永久性重定向。该状态码表示请求的资源已被分配了新的 URI,以后应使用资源现在所指的 URI。也就是说,如果已经把资源对应的 URI 保存为书签了,这时应该按location
首部字段提示的 URI 重新保存。302 Found
临时重定向。该状态吗表示请求的资源已被分配了新的 URI,希望用户本次能使用新的 URI 访问。303 See Other
该状态码表示由于请求对应的资源存在着另一个 URI,应使用 GET 方法定向获取请求的资源。304 Not Modified
表示客户端发送附带条件的请求时,服务器端允许请求访问资源,但因发生请求未满足条件的情况后,直接返回 304。307 Temporary Redirect
临时重定向。跟 302 有着相同的含义。
4xx 客户端错误。
400 Bad request
表示请求报文中存在语法错误。当错误发生时,需修改请求的内容后再次发送请求。401 Unauthorized
表示发送的请求需要有通过 HTTP 认证(BASIC 认证、DIGEST 认证)的认证信息。另外若之前已进行过 1 次请求,则表示用户认证失败。返回含有 401 的响应必须包含一个适用于被请求资源的 WWW-Authenticate 首部用以质询用户信息。当浏览器初次接收到 401 响应,会弹出认证用的对话窗口
403 Forbidden
表明对请求资源的访问被服务器拒绝了。404 Not Found
该状态码表明服务器上无法找到请求的资源,除此之外,也可以在服务器拒绝请求且不想说明理由时使用。
5xx 服务器错误
500 Internal Server Error
表明服务器端在执行请求时发生了错误。503 Service Unavailable
表明服务器暂时处于超负载或正在进行停机维护,现在无法处理请求。
第五章代理是一种有转发功能的应用程序,他扮演了位于服务器和客户端中间人的角色。
- 网关是转发其他服务器通信数据的服务器。
- 隧道是在相隔甚远的客户端和服务端两者之间进行中转,并保持双方通信连接的应用程序。
隧道的目的是确保客户端能与服务器进行安全的通信。
第六章
Content-Type
字段表示报文主体的对象类型:text/plain
4 种 HTTP 首部字段类型
- General Header Fields 通用首部字段
- 请求报文和响应报文两方都会使用的首部
- Request Header Fields 请求首部字段
- 从客户端向服务器端发送请求报文时使用的首部。
- Response Header Fields 响应首部字段
- 从服务器端向客户端返回响应报文时使用的首部。
- Entiry Header Fields 实体首部字段
- 针对请求报文和响应报文的实体部分使用的首部。补充了资源内容更新时间等与实体有关的信息。
通用首部字段
首部字段名 | 说明 |
---|---|
Cache-control | 控制缓存的行为 |
Connection | 逐跳首部、连接的管理 |
Date | 创建报文的日期时间 |
Transfer-Encoding | 指定报文主体的传输编码方式 |
Via | 代理服务器的相关信息 |
Warning | 错误通知 |
- 请求首部字段
首部字段名 | 说明 |
---|---|
Accept | 用户代理可处理的媒体类型 |
Accept-Charset | 优先的字符集 |
Accept-Encoding | 优先的内容编码 |
Accept-Language | 优先的语言 |
Authorization | Web 认证信息 |
Expect | 期待服务器的特定行为 |
From | 用户的电子邮箱地址 |
Host | 请求资源所在服务器 |
If-Match | 比较实体标记 |
If-Modified-Since | 比较资源的更新时间 |
If-None-Match | 比较实体标记 |
If-Range | 资源未更新时发送实体 Byte 的范围请求 |
If-Unmodified-Since | 比较资源的更新时间 |
Max-Forwards | 最大传输逐跳数 |
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-Range|实体主体的位置范围| |Content-Type|实体主体的媒体类型| |Expires|实体主体过期的日期时间| |Last-Modified|资源的最后修改日期时间|
通用首部字段是指,请求报文和响应报文双方都会使用的首部。
- 通过指定首部字段 Cache-control 的指令,就能操作缓存的工作机制 。
- 在 Cache-Control 中,缓存响应指令
- public 指令 表明其他用户也可以利用缓存。
- private 指令表示以特定的用户作为对象。
- 缓存服务器会对该特定用户提供资源缓存的服务,对于其他用户发送过来的请求,代理服务器则不会返回缓存。
- no-cache 指令是强制向原服务器再次验证,为了防止从缓存中返回过期的资源。
- 从服务端返回来过的带参数的 no-cache,指定参数值的首部字段对应的响应报文就不能使用缓存。无参数值的首部字段可以使用缓存。
- no-store 规定缓存不能再本地储存请求或响应的任一部分。也就是不进行缓存。
- max-age 数值代表资源保存为缓存的最长时间。
- min-fresh 要求缓存服务器返回至少还未过指定时间的资源。超过指定的时间则无法作为响应返回。
- max-stale 可指示缓存资源,即使过期也照样接收。
- 指定数值,则在数值之内缓存都有效
- 不指定数值,则无论多长时间缓存都有效。
- only-if-cached 表示客户端仅在缓存服务器本地缓存目标存在的情况下才会要求其返回。
- must-revalidate 代理会向源服务器再次验证即将返回的响应缓存目前是否仍然有效。
- proxy-revalidate 指令要求所有的缓存服务器在接收到客户端带有该指令的请求返回响应之前,必须再次验证缓存的有效性。
- no-transform 规定无论是请求还是响应中,缓存都不能改变实体主体的媒体类型。这样做可防止缓存或代理压缩图片等类似操作
- Connection 可以控制代理不再转发的首部字段。可以管理持久连接
- HTTP/1.1 默认连接都是持久连接(keep-alive),当服务器端想明确断开连接时,则指定 Connection 首部字段为
close
- Date 表明创建 HTTP 报文的日期和时间。
- Trailer 会事先说明在报文主体后记录了哪些首部字段。
- Transfer-Encoding 规定了传输报文主体时采用的编码方式。
- Upgrade 用于检测 http 协议及其他协议是否可以使用其他的通信协议
- Via 首部字段用于追踪客户端与服务器之间的请求和响应报文的传输路径。
- Warning 通常会告知用户一些与缓存相关的问题的警告。格式为:
Warning: [警告码][警告的主机:端口号] “[警告的内容]” ([日期和事件])
请求首部字段
- Accept 首部字段可通知服务器,用户代理能够处理的媒体类型及媒体类型的相对优先级。
- 想要给显示的媒体类型增加优先级,则使用 q=来额外表示权重值,用
;
隔离。权重值 q 的范围为 0~1,默认权重为 q=1.0。 - 当服务器提供多种内容时,将会首先返回权重值最高的媒体类型。
- Accept-Charset 首部字段可用来通知服务器用户代理支持的字符集及字符集的相对优先顺序。可指定权重值 q 来表示相对优先级。
- Accept-Encoding 用来告知服务器用户代理支持的内容编码及内容编码的优先级顺序。可以一次性指定多种编码。可以采用 q 来表示权重值。也可以用
*
来表示任意的编码格式。 - gzip (GNU zip)
- compress
- deflate
identity 不执行压缩或不会变化的默认编码格式。
Accept-Encoding: gzip, deflate, br
Accept-Language 用来告知服务器用户代理能够处理的自然语言集,以及相对优先级。可指定多种语言集。用 q 来表示权重值,有限返回权重值高的。
accept-language: zh-CN,zh;q=0.9
Authorization 用来告知服务器用户代理的认证信息。
Authorization: OLS:32pnW+rxXwSMkePCo3dIjfmyzvg=
Expect 客户端使用 expect 字段来告知服务器,期望出现的某种特定行为。
- From 用来告知服务器使用用户代理的用户电子邮件的地址。
- Host 会告知服务器,请求的资源所处的互联网主机名和端口号。如果相同的 ip 地址下部署运行多个域名,那么服务器就无法理解是哪个域名对应的请求。所以就需要 host 来指出请求的主机名。
- If-XXX 这种样式的请求首部字段,都可称为条件请求。服务器接收到附带条件的请求后,只有判断指定条件为真时,才会执行请求。
- If-Modified-Since 会告知服务器,在指定的值之后更新过资源,则处理请求。如果在之后没有更新过,则返回状态码 304。
- If-Unmodified-Since 与 If-Modified-Since 相反
- If-None-Match 跟 If-Match 相反
- If-Range 字段若是跟 ETag 值或更新的日期时间匹配一致,那么就作为范围请求处理。否则返回全体资源。
- Max-Forwards 请求经过多台代理服务器进行转发时,每转发一次,Max-Forwards 的值就减 1,当为 0 时,就会返回响应。
- Proxy-Authorization 接收到代理服务器发来的认证质询时,客户端会发送包含首部字段 Proxy-Authorization 的请求,以告知服务器认证所需要的信息。
- 这个行为发生在客户端和代理之间。
- 客户端与服务器之间的认证,使用 Authorization 可起到相同的作用
- Range 指定范围的资源请求。
- 能够处理请求返回状态码 206
无法处理该范围请求,返回 200 及全部资源
Range: bytes=5001-10000
Referer 告知服务器请求资源的原始 URI(路径)。
- TE 会告知服务器能够处理响应的传输编码方式及相对优先级。
- User-Agent 会将创建请求的浏览器和用户代理名称等信息传达给服务器。
- 如果经过代理,那么中间也很可能被添加代理服务器的名称。
响应首部字段
- Accept-Ranges 用来告知服务器是否能处理范围请求。
- 指定两种值,可处理为
bytes
,反之则为none
。 Age 能够告知客户端,源服务器在多久前创建了响应。单位为秒。
Age: 1941638
ETag 能告知客户端实体标识。将资源以字符串形式做唯一标识的方式。当资源更新时,ETag 值也需要更新。
- Location 可以将响应接收方引导至某个与请求 URI 位置不同的资源。
- Proxy-Authenticate 会把由代理服务器所要求的认证信息发送给客户端。
- Retry-After 告知客户端盖在多久之后再次发送请求。
- Server 告知客户端当前服务器上安装的 HTTP 服务器应用程序的信息。
Vary 可对缓存进行控制,如果指定字段的值,与源服务器字段的值相同,则直接从缓存中返回响应。反之,则需要先从源服务器端获取资源后才能作为响应返回。
Vary: Accept-Encoding
首部字段 WWW-Authenticate 用于 HTTP 认证访问。他会告知客户端适用访问请求 URI 所指定资源的认证方案(Basic 或 Digest)和带参数提示的质询。
实体首部字段
- Allow 通知客户端能够支持 Request 指定资源的所有 HTTP 方法。
- Content-Type 指定内容编码方式。内容编码是指在不丢失实体信息的情况下,所进行的压缩。
- Content-Language 实体主体使用的语言。
- Content-length 表明了实体主体部分 的大小。
- Content-location 表示报文主体返回资源对应的 URI
Content-MD5 是一串由 MD5 算法生成的值,其目的在于检查报文主体在传输过程中是否保持完整,以及确认传输到达。
Content-MD5: d0c827071e3b6ca84004e4734b36537b
Content-Range 范围请求。
Content-Type 实体主体内对象的媒体类型。
Content-Type: text/html; charset=utf-8
Expires 会将资源失效的日期告知客户端。
Expires: Sat, 09 Nov 2019 07:47:32 GMT
Last-Modified 指明资源最终修改的时间。
Last-Modified: Sat, 09 Nov 2019 07:42:52 GMT
Cookie 的工作机制是用户识别及状态管理。web 网站为了管理客户的状态会通过 web 浏览器,把一些数据临时写入用户的计算机内。接着当用户访问该 web 网站时,可通过通信方式取回之前存放的 Cookie
- expires 指定浏览器可发送 Cookie 的有效期。
- path 可用于限制指定 Cookie 的发送范围的文件目录。
- domain 如:指定 example.com,除了 example.com 外,www.example.com 或 www2.example.com 等都可以发送 Cookie。
- 因此,除了针对具体指定的多个域名发送 cookie 外,不指定 domain 属性显得更安全。
- secure 属性用于限制 web 页面仅在 https 安全连接时,才可以发送 cookie。
- 当省略时,不论 http 和 https 都会对 cookie 进行回收。
- HttpOnly 它使 jsvascript 脚本无法获得 Cookie。其主要目的是为了防止跨站脚本攻击(Cross-site-scriping, XSS)对 Cookie 的信息窃取。
- 进行设置后,web 页面内还可以对 Cookie 进行读取操作,但使用 JavaScript 的
document.cookie
就无法读取附加 httponly 属性后的内容了。因此,也就无法在 XSS 中利用 js 劫持 Cookie 了。
其他首部字段。http 首部字段是可以自行扩展的。所以在 web 服务器和浏览器的应用上,会出现各种非标准的首部字段。,
X-XSS-Protection
,DNT
,P3P
。- X-Frame-Options 属于 http 相应首部,用于控制网站内容在其他 web 网站的 Frame 标签内的显示问题。主要为了防止点击劫持(clickjacking)。
- DENY:拒绝
SAMEORIGIN:仅同源域名下的页面匹配时许可。
x-frame-options: SAMEORIGIN
x-xss-protection 针对跨站脚本攻击(XSS)的一种对策,用户控制浏览器 XSS 防护机制的开关。
- 0:将 XSS 过滤设置成无效状态
- 1:将 XSS 过滤设置成有效状态
- DNT (do noet track)为拒绝个人信息被收集,是表示拒绝被精准广告追踪的一种方法。
- 0:同意被追踪
- 1:拒绝被追踪
- P3P 可以让 web 网站上的个人隐私变成一种仅供程序可理解的形式,以达到保护用户隐私的目的。
在 http 的多种协议中,通过给非标准参数加上前缀 X-,用来区别于标准参数。