《图解http》的学习

http(超文本传输协议)是 web 客户端与服务器之间资源交互的基础通信规范,web 的所有内容传输都基于 http 协议完成

第一章

1、tcp/ip协议族分层管理

http 是 tcp/ip 协议族的子集,互联网整体基于 tcp/ip 协议族运作,协议采用分层管理设计,实现职责解耦,某一层的改动不会影响其他层,tcp/ip 分为四层:

1)应用层 —— 向用户提供服务的通信活动,http协议、ftp、dns都属于这一层,是http协议所在的一层

2)传输层 —— 提供网络中两台计算机之间的数据传输,核心协议为tcp(传输控制)协议和udp(用户数据报)协议,http基于tcp协议实现可靠的端到端传输

3)网络层 —— 处理网络上流动的数据包,核心是ip,负责为数据包选择传输路径,将数据包准确的送到目的地

4)链路层 —— 处理网络硬件部分,包括网卡、驱动、物理传输媒介等

2、tcp/ip通信传输流

发送端从应用层http向下逐层传输,每经过一层后添加该层的首部信息,完成数据封装

接收端从链路层向上逐层传同步输,每经过一层消去对应的首部信息,完成数据解封装,最终在应用层还原http请求

3、与http关系密切的三大协议
ip协议(网络层)

将数据包准确的送到目标地址

1)ip地址为节点分配的网络地址,用于定位网络中的节点

2)mac地址为网卡所属的固定物理地址,用于局域网内的节点寻址

arp协议机制

1)arp协议(地址解析协议)可通过目标ip地址反查对应的mac地址,实现数据包的链路层转发

路由特性

1)数据包在互联网中通常通过多台网络设备中转,无法掌握全网的传输路径,仅负责下一跳的转发地址

tcp协议(传输层)

为http提供可靠的字节流服务,将大块的数据分割为报文段为单位的数据包进行管理,确保数据完整准确的送达

1)三次握手机制,确保tcp连接可靠建立

​ 客户端发送带SYN(同步)标志的数据包,向服务器发起连接

​ 服务器返回带SYN/ACK(同步/确认)标志的数据包,确认收到客户端请求并回传同步信号

​ 客户端发送带ACK(确认)标志的数据包,告诉服务器连接确认完成,握手结束

* 若三次握手过程中在某一阶段中断了,tcp协议会以相同顺序重新发送数据包以确保可靠性
dns服务(应用层)

提供域名和ip地址的双向解析服务,计算机仅能处理数字形式的ip地址,dns作为桥梁,让http请求可通过域名找到目标服务器的ip地址

url与uri

1)uri(统一资源标识符)—— 仅用来唯一标识一个网络资源,部分uri(如url)可直接访问,部分uri(如urn、相对uri)则无法单独定位资源

2)url(统一资源定位符)—— 包含协议与地址,可用于直接定位并访问资源,所有 URL 都是 URI,但 URI 不一定是 URL(例如https://rhien.cn/photo/123.png是完整的url路径(同时也是绝对url),可直接访问并获取资源,其中photo/123.png为相对uri,相对uri单独使用无法定位资源,需结合基础uri https://rhien.cn/才能使用)

第二章

1、http通信的核心模型

1)通信角色 —— http协议通信的两端必然是一端为客户端,另一端为服务端

2)核心交互规则 —— 请求必然由客户端发起,服务端仅在收到请求后才会回应

2、http请求与相应的报文结构

http通信的基本单位是http报文,分别为请求报文(客户端>服务端)和响应报文(服务端>客户端),整体由报文首行、空行、报文主体三部分组成

1)请求报文结构

GET /index.htm HTTP/1.1  // 请求行
Host: hackr.jp            // 首部字段
User-Agent: Firefox/13.0
Accept: text/html

// 空行(CR+LF)
name=ueno&age=37         // 报文主体(可选)

核心组成部分:

​ 请求行 —— 包含请求方法、请求 uri、http 协议版本

​ 首部字段 —— 分为请求首部、通用首部、实体首部,补充请求的附加信息、客户端属性、资源要求等

​ 空行 —— 固定分隔符,分隔报文首部与主体

​ 内容主体 —— post 等方法传输的主体数据

2)响应报文结构

HTTP/1.1 200 OK  // 状态行
Date: Tue, 10 Jul 2012 06:50:15 GMT  // 首部字段
Content-Length: 362
Content-Type: text/html

// 空行(CR+LF)
<html>...</html>        // 报文主体

核心组成部分:

​ 状态行 —— 包含http协议版本、状态码、原因短语、标识请求的处理结果

​ 首部字段 —— 分为响应首部、通用首部、实体首部、补充响应的附加信息、服务器属性、实体描述等

​ 空行 —— 固定分隔符,分隔报文首部与主体

​ 实体主体 —— 响应返回的内容资源(html、图片、json等)

3、http的无状态(stateless)特性

http协议本身不对请求和响应之间的通信状态保持进行持久化保存,每次请求都是完全独立的,协议不记录之前的请求和响应信息

这种简化协议的设计可以减少服务器cpu内存的资源消耗,可快速处理大量的并发请求,不过缺点就是无法满足需要保持用户状态的场景(如用户登录、购物车、多页面会话),现有的解决方案可采取cookie技术,通过在请求 / 响应报文中传递cookie信息,实现客户端与服务器之间的状态管理

4、http/1.1的核心请求方法

1)GET —— 获取资源(1.0/1.1)

请求 URI 指定的资源,服务器解析后返回资源内容,正常返回 200 OK

2)POST —— 传输实体主体(1.0/1.1)

用于向服务器提交数据,虽 GET 也可传输主体,但规范上 POST 的核心语义是提交实体,而非获取响应主体

3)PUT —— 传输文件(1.0/1.1)

向 URI 指定位置上传文件,本身无验证机制,存在安全风险,普通 Web 网站默认不开放,仅 REST 架构或带强验证的场景使用

4)HEAD —— 获取报文首部(1.0/1.1)

与 GET 逻辑一致,但服务器仅返回响应首部,不返回实体主体,用于确认资源有效性、更新时间等

5)DELETE —— 删除文件(1.0/1.1)

删除 URI 指定的资源,与 PUT 对应,无验证机制,默认不开放,仅特定场景使用

6)OPTIONS —— 询问支持的方法(1.1)

让服务器环回请求报文,确认请求经过的代理 / 中转路径,易引发 XST 跨站追踪攻击,实际很少使用

7)CONNECT —— 隧道协议连接代理(1.1)

要求与代理服务器建立网络隧道,通过 SSL/TLS 加密通信内容,实现加密数据的中转传输

5、持久连接(长连接)与管线化(http性能优化)

http/1.0 默认每次http请求都要经历「tcp 建立→请求→响应→tcp 断开」的完整流程,一个包含多图片的页面会产生大量 tcp 连接重复建立 / 断开,造成额外的网络开销和页面加载延迟

持久连接(长连接)

只要通信任意一端没有明确提出断开连接,就保持tcp连接状态,一次tcp连接可处理多次http请求或响应

http1.1默认开启持久连接,http1.0则需要手动开启(Connection: keep-alive)

启用持久连接后减少tcp连接重复建立/断开的开销,减轻服务器负载,缩短web页面的加载时间

管线化

持久连接(长连接)的升级版,无需等待上一个请求的响应返回,即可并行发送多个http的请求

比普通的持久连接性能更高,请求数量越多,性能提升越明显,初步解决了http请求的队头阻塞问题

cookie的状态管理

cookie是弥补http无状态特性的核心技术,实现客户端与服务端的会话状态管理

核心工作流程

1)服务器在响应报文中通过Set-Cookie首部字段,向客户端下发cookie信息(包含名称、值、有效期、域、路径、安全属性等)

2)客户端浏览器保存cookie,下次向同一服务器发起请求时,自动在请求首部的Cookie字段中携带已保存的cookie值

3)服务器接收请求中的cookie后,对比服务器端的记录,识别客户端身份与历史状态,实现会话管理

关键安全属性

1)domain/path —— 控制cookie的作用域,限制cookie的发送范围

2)secure —— 仅在https安全通信时才会发送cookie

3)HttpOnly —— 禁止JavaScript脚本读取cookie,防止xss跨站脚本攻击窃取cookie

第三章

—— http报文内的http信息

1、http报文基础

使用http协议交互信息的称为http报文,分为客户端的请求报文和服务端的响应报文

基础结构

报文是由CR+LF(回车+换行)的多行字符串文本,分为两部分

1)报文首部 —— 包含请求/响应的条件、属性和配置信息

2)报文主体 —— 传输的有效载荷信息(不是必须存在的)

* 报文首部和主体之间,通过一个空行(CR+LF)分隔

请求报文和响应报文的结构

http报文的首部分为四类:通用首部、请求首部、响应首部和实体首部,也支持扩展自定义首部(cookie、负载均衡等)

请求报文结构

核心组成:请求行+各种首部(请求/通用/实体首部)+空行+请求主体

1)请求行 —— 包含请求方法、请求uri、http版本,用于声明客户端的请求目的

响应报文结构

核心组成:状态行+各种首部(请求/通用/实体首部)+空行+响应主体

1)状态行 —— 包含http版本、状态码、状态码原因短语,用于声明服务端对请求的处理结果

3、编码优化:提升http传输速率

通过编码处理,平衡传输速率与服务器处理开销,在不改变实体信息的前提下减少传输量、优化体验

报文主体与实体主体的差异

1)报文 —— http通信的基本单位,8位字节流

2)实体 —— 请求/响应的有效载荷数据(核心传输内容),由实体首部+实体主体组成

* 通常两者内容相等,仅当传输中进行编码操作时,实体主体内容发生变化,才会与报文主体不同

内容编码

服务端对实体主体进行压缩编码后传输,客户端接收后自行解码还原,不改变实体信息,大幅减少传输数据量

常用编码格式 —— gzip(gnu zip)、compress(unix标准压缩)、deflate、identity(不进行编码)

分块传输编码

适用于实体数据量较大时,无需等待全部数据传输完成,即可让浏览器逐步渲染页面

实现原理 —— 将实体主体拆分为多个块,每一块用十六进制标记块大小,最后一块用0(CR+LF)标记传输结束

* 分块的实体主体由接收方客户端负责解码,还原为编码前的完整实体

4、多部份对象集合:一次传输多种数据

借鉴mime机制,在一份http报文中容纳多种不同类型的实体,一次请求/响应可同时传输文本、图片、文件等多种类型数据

常用类型

1)multipart/form-data —— web表单上传时使用

2)multipart/byteranges —— 状态码206(Partial Content,部分内容)响应报文,包含多个范围的内容时使用

* 多部份对象的每个分段都可拥有独立的首部,分段之间用boundary定义的分隔符划分,整体以--boundary-- 标记结束

5、范围请求:实现断点续传

仅请求资源的指定字节范围,无需下载完整资源,解决网络中断后需重新下载完整资源的问题

实现方式:通过请求首部的Range字段指定资源的字节范围

1)5001-10000字节 —— Range: bytes=5001-10000

2)5001字节之后的全部内容 —— Range: bytes=5001-

3)多段范围 —— Range: bytes=0-3000, 5000-7000

响应结果

1)范围请求成功 —— 服务端返回状态码206 Partial Content,以及对应范围的实体内容

2)不支持范围请求 —— 返回状态码200 OK和完整的实体内容

6、内容协商:返回最适配的内容

客户端与服务端协商响应资源的内容,为客户端返回最适合的资源(如语言、编码、媒体格式等),中文用户返回中文页面、英文用户返回英文页面等

核心判断依据:请求首部的协商字段

1)Accept —— 客户端可接收的媒体类型

2)Accept-Charset —— 客户端可接收的字符集

3)Accept-Encoding —— 客户端可接收的内容编码

4)Accept-Language —— 客户端可接收的自然语言

协商的三种类型

1)服务器驱动协商 —— 服务端根据请求首部信息,自然返回最适合的资源

2)客户端驱动协商 —— 客户端从服务端返回的可选资源列表中,手动/自动选择最适合的资源

3)透明协商 —— 服务端驱动与客户端驱动的结合,由服务端与客户端分别处理一部分协商逻辑

第四章

—— 返回结果的http状态码

1、状态码基础

结构规则:状态码由三位数字与原因短语组成,第一位数字定义了响应类型

状态码大类总览:

1)1xx —— 信息性状态码,服务端已接收请求,正在处理中

2)2xx —— 成功状态码,请求已被服务端正常处理完毕

3)3xx —— 重定向状态码,需要客户端执行附加操作(如跳转)才能完成请求

4)4xx —— 客户端错误状态码,请求存在错误,服务端无法处理

5)5xx —— 服务端错误状态码,服务端处理请求时发生内部错误

2、2xx成功:请求正常处理完成

2xx状态码代表客户端的请求被服务端正常处理并完成

200 OK

1)最常用的成功状态码,代表请求被正常处理

2)GET 请求会返回请求资源的完整实体主体;HEAD 请求仅返回响应首部,不返回实体主体

204 NoContent

1)请求处理成功,但响应中不包含任何实体主体,也不允许返回实体主体

2)适用于客户端进项服务端发送信息,不需要服务端返回新内容(如纯更新操作),浏览器接收到该状态码后,页面不会刷新

206 Partial Content

1)客户端发起范围请求(通过Range首部指定字节范围),服务端成功执行了该部分的GET请求

2)响应报文中会通过Content-Range首部,明确返回的实体内容的字节范围,对应第三章的断点续传

3、3xx 重定向:需要客户端附加操作完成请求

3xx状态码表示需要客户端执行跳转、重新发起请求等附加操作,才能完成请求

301 Moved Permanently(永久重定向)

1)请求的资源已被重新分配的新的uri,后续所有请求都将使用新的uri访问

2)适用于域名更换、资源路径永久变更、浏览器会缓存新的地址,后续访问会自动跳转

302 Found (临时重定向)

1)请求的资源临时分配了新的uri,仅本次请求使用新的uri,未来仍然使用原uri

2)与301的区别是浏览器不会缓存新的地址

303 See Other

1)与302功能类似,但是客户端必须使用GET方式访问新的uri

2)适用于POST请求处理完毕后,跳转到结果页面,避免刷新页面重复提交POST请求

* 当301/302/303响应返回时,几乎所有浏览器都会自动将POST请求改为GET请求,去掉请求主体,重新发起请求

304 Not Modified

1)客户端发起带条件的请求(如If-Modified-Since等协商缓存首部)时,服务端允许请求访问,但资源未发生变化,无需重新返回资源

* 304与重定向无关,响应中不包含任何实体主体,用于http协商缓存场景

4、4xx客户端错误:请求存在问题,服务端无法处理

4xx类状态码表示错误的原因在客户端,服务端无法处理该请求

400 BadRequest

1)请求报文中存在语法错误、格式错误或参数错误,服务端无法理解该请求

2)浏览器将该状态码和200状态码同等对待,不做特殊跳转,需开发者自行处理错误信息

401 Unauthorized

1)请求需要通过http认证(BASIC认证、DIGEST认证),或认证信息错误、认证失败

2)首次返回401时,浏览器会弹出认证输入窗口,再次返回401,则代表用户认证失败

403 Forbidden

1)表示服务端拒绝了该请求的访问

2)常见的ip被封禁、文件权限不足、访问了禁止公开的资源、未获的对应权限的操作都会返回403

404 Not Found

1)服务端上没找到请求的资源

2)服务端拒绝请求,但不想明确返回拒绝原因时,也可以使用404状态码

5、5xx服务端错误:服务端处理请求时发生异常

5xx类状态码表示错误的原因在服务端,处理请求时发生了异常

500 Internal Server Error

1)服务端执行请求时发生了内部错误

2)常见于服务端应用程序存在bug、代码执行异常、服务故障等

503 Service Unavailable

1)服务端暂时无法处理请求,服务不可用

2)常见于服务器过载、停机维护、临时限流,如果明确恢复时间可通过Retry-After首部告知客户端

* 实际业务中返回的状态码可能与实际感知不同