http入门笔记

该笔记是在学习《透视 HTTP 协议》时整理,还参考了网上的其他资料。鄙人只是网络世界的搬运整理工😂。

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220317/6935d109cbc64fa58c3177a90fd33098.png?imageView2/0/interlace/1/q/50|imageslim

http(超文本传输协议)是一个用在计算机世界里的协议。它使用计算机能够理解的语言确立了一种计算机之间交流通信的规范,以及相关的各种控制和错误处理方式。

http 是一个在计算机世界里专门在两点之间传输文字、图片、音频、视频等超文本数据的约定和规范。

http 不是编程语言,但是可以用编程语言去实现 HTTP,告诉计算机如何用 HTTP 来与外界通信。

在互联网世界里,HTTP 通常跑在 TCP/IP 协议栈之上,依靠 IP 协议实现寻址和路由、TCP 协议实现可靠数据传输、DNS 协议实现域名查找、SSL/TLS 协议实现安全通信。此外,还有一些协议依赖于 HTTP,例如 WebSocket、HTTPDNS 等。这些协议相互交织,构成了一个协议网,而 HTTP 则处于中心地位。

HTTP 传输的不是 TCP/UDP 这些底层协议里被切分的杂乱无章的二进制包(datagram),而是完整的、有意义的数据,可以被浏览器、服务器这样的上层应用程序处理。

我们通常所说的“上网”实际上访问的只是互联网的一个子集“万维网”(World Wide Web),它基于 HTTP 协议,传输 HTML 等超文本资源,能力被限制在 HTTP 协议之内。

互联网上还有许多万维网之外的资源,例如常用的电子邮件、BT 和 Magnet 点对点下载、FTP 文件下载、SSH 安全登录、各种即时通信服务等等,它们需要用各自的专有协议来访问。

不过由于 HTTP 协议非常灵活、易于扩展,而且“超文本”的表述能力很强,所以很多其他原本不属于 HTTP 的资源也可以“包装”成 HTTP 来访问,这就是我们为什么能够总看到各种“网页应用”——例如“微信网页版”“邮箱网页版”——的原因。

TCP/IP 协议实际上是一系列网络通信协议的统称, 其中最核心的两个协议是TCP(Transmission Control Protocol/传输控制协议)和IP(Internet Protocol),其他的还有 UDP、ICMP、ARP 等等,共同构成了一个复杂但有层次的协议栈。

HTTP 是超文本传输协议,TCP 是传输控制协议,都是传输,区别是,HTTP 传输的是完整的、有意义的数据,可以被浏览器、 服务器这样的上层应用程序处理,HTTP 不关心寻址、路由、数据完整性等传输细节,而要求这些工作都由下层(基本都由 TCP)来处理。 TCP 传输的是可靠的、字节流和二进制包。

TCP 是 HTTP 得以实现的基础,HTTP 协议运行在 TCP/IP 上,HTTP 可以更准确地称为 “HTTP over TCP/IP”。

URI(Uniform Resource Identifier),中文名称是 统一资源标识符,使用它就能够唯一地标记互联网上资源。

URI 另一个更常用的表现形式是 URL(Uniform Resource Locator), 统一资源定位符,也就是我们俗称的“网址”,它实际上是 URI 的一个子集,这两者几乎是相同的,差异不大,除非写论文,否则不用特意区分。

SSL 的全称是“Secure Socket Layer”,网景公司发明,当发展到 3.0 时被标准化,改名为 TLS,即“Transport Layer Security”。 所以 TLS 跟 SSL 是一个东西,相当于张君宝的 2.0 版本是张三丰。

SSL 是一个负责加密通信的安全协议,建立在 TCP/IP 之上,在 HTTP 协议之下。

  • 匿名代理:完全“隐匿”了被代理的机器,外界看到的只是代理服务器;
  • 透明代理:顾名思义,它在传输过程中是“透明开放”的,外界既知道代理,也知道客户端;
  • 正向代理:靠近客户端,代理的对象是客户端,代表客户端向服务器发送请求;

正向代理是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器,比如 Google),然后代理向原始服务器转交请求并将获得的内容返回给客户端。

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220317/22475408cd734b9c861b345040e356f4.png?imageView2/0/interlace/1/q/50|imageslim
正向代理

  • 反向代理:靠近服务器端,代理代理的对象是服务端,代表服务器响应客户端的请求

反向代理指的是代理服务器根据客户端的请求,从其关系的一组或多组后端服务器(如 Web 服务器)上获取资源,然后再将这些资源返回给客户端的过程,客户端只会得知代理服务器的 IP 地址,而不知道在代理服务器后面的服务器集群的存在。

当一个代理服务器能够代理外部网络上的主机,访问内部网络时,这种代理服务的方式称为反向代理服务。

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220317/6a2b4d26c0bf43cd9494df793c48a814.png?imageView2/0/interlace/1/q/50|imageslim
反向代理

万维网关键技术

  • URI:即统一资源标识符,作为互联网上资源的唯一身份;
  • HTML:即超文本标记语言,描述超文本文档;
  • HTTP:即超文本传输协议,用来传输超文本。

基于这三项关键技术就可以把超文本系统完美地运行在互联网上,让各地的人们能够自由地共享信息,这个系统称为“万维网”(World Wide Web),也就是我们现在所熟知的 Web。

结构简单,设置之初设想系统里的文档都是只读的,所以只允许用 GET 动作从服务器上获取 HTML 纯文本格式的文档,并且在响应请求之后立即关闭连接,功能非常有限。

HTTP/1.0 并不是一个标准,只是记录已有实践和模式的一份参考文档,不具有实际的约束力,相当于一个备忘录。

在多方面增强了 0.9 版,形式上已经和我们现在的 HTTP 差别不大了,例如:

  • 增加了 HEAD、POST 等新方法;
  • 增加了响应状态码,标记可能的错误原因;
  • 引入了协议版本号概念;
  • 引入了 HTTP Header(头部)的概念,让 HTTP 处理请求和响应更加灵活;
  • 传输的数据不再仅限于文本。

是一个正式的标准,而不是一份可有可无的参考文档,只要用到 HTTP 协议,就必须严格遵守这个标准。

主要变更:

  • 增加了 PUT、DELETE 等新的方法;
  • 增加了缓存管理和控制;
  • 明确了连接管理,允许持久连接;
  • 允许响应数据分块(chunked),利于传输大文件;
  • 强制要求 Host 头,让互联网主机托管成为可能。

由 google 主导,基于 google 的 SPDY 协议为基础开始制定新版本的 HTTP 协议,最终在 2015 年发布了 HTTP/2。

主要特点:

  • 二进制协议,不再是纯文本;
  • 可发起多个请求,废弃了 1.1 里的管道;
  • 使用专用算法压缩头部,减少数据传输量;
  • 允许服务器主动向客户端推送数据;
  • 增强了安全性,“事实上”要求加密通信。

由 google 主导,基于 google 的 QUIC 协议为基础开始制定新版本的 HTTP 协议。

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220317/87869e9a3d0d4eaba7c9d6fe0798674f.png?imageView2/0/interlace/1/q/50|imageslim
TCP/IP分层模型

这里的层次顺序是“从下往上”数的,所以第一层就是最下面的一层。

第一层叫“链接层”(link layer),负责在以太网、WiFi 这样的底层网络上发送原始数据包,工作在网卡这个层次,使用 MAC 地址来标记网络上的设备,所以有时候也叫 MAC 层。

第二层叫“网际层”或者“网络互连层”(internet layer),IP 协议就处在这一层。因为 IP 协议定义了“IP 地址”的概念,所以就可以在“链接层”的基础上,用 IP 地址取代 MAC 地址,把许许多多的局域网、广域网连接成一个虚拟的巨大网络,在这个网络里找设备时只要把 IP 地址再“翻译”成 MAC 地址就可以了。

第三层叫“传输层”(transport layer),这个层次协议的职责是保证数据在 IP 地址标记的两点之间“可靠”地传输,是 TCP 协议工作的层次,另外还有它的一个“小伙伴”UDP。

TCP 是一个有状态的协议,需要先与对方建立连接然后才能发送数据,而且保证数据不丢失不重复。而 UDP 则比较简单,它无状态,不用事先建立连接就可以任意发送数据,但不保证数据一定会发到对方。两个协议的另一个重要区别在于数据的形式。TCP 的数据是连续的“字节流”,有先后顺序,而 UDP 则是分散的小数据包,是顺序发,乱序收。

协议栈的第四层叫“应用层”(application layer),由于下面的三层把基础打得非常好,所以在这一层就“百花齐放”了,有各种面向具体应用的协议。例如 Telnet、SSH、FTP、SMTP,HTTP 等等。

Tip
MAC 层(链接层)的传输单位是帧(frame),IP 层(网络互联层)的传输单位是包(packet),TCP 层传输层的传输单位是段(segment), HTTP (应用层)的传输单位则是消息或报文(message)。这些名词并没有什么本质的区分,可以统称为数据包。

OSI 分层模型在发布的时候就明确地表明是一个“参考”,不是强制标准。这是因为 TCP/IP 等协议已经在许多网络上实际运行,不可能推翻重来。

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220317/4ddd78194c284518a2ce2db4cfab2a3c.png?imageView2/0/interlace/1/q/50|imageslim
OSI网络模型

  • 第一层:物理层,网络的物理形式,例如电缆、光纤、网卡、集线器等等;
  • 第二层:数据链路层,它基本相当于 TCP/IP 的链接层;
  • 第三层:网络层,相当于 TCP/IP 里的网际层;
  • 第四层:传输层,相当于 TCP/IP 里的传输层;
  • 第五层:会话层,维护网络中的连接状态,即保持会话和同步;
  • 第六层:表示层,把数据转换为合适、可理解的语法和语义;
  • 第七层:应用层,面向具体的应用传输数据。

对比一下就可以发现,TCP/IP 是一个纯软件的栈,没有网络应有的最根基的电缆、网卡等物理设备的位置。而 OSI 则补足了这个缺失, 在理论层面上描述网络更加完整。

OSI 还为每一层标记了明确了编号,最底层是一层,最上层是七层,而 TCP/IP 的层次从来只有名字而没有编号。

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220317/539751215a0b45ada0a373f8289ca232.png?imageView2/0/interlace/1/q/50|imageslim
两个分层模型的对应关系

所谓的“四层负载均衡”就是指工作在传输层上,基于 TCP/IP 协议的特性,例如 IP 地址、端口号等实现对后端服务器的负载均衡。

所谓的“七层负载均衡”就是指工作在应用层上,看到的是 HTTP 协议,解析 HTTP 报文里的 URI、主机名、资源类型等数据,再用适当的策略转发给后端服务器。

有一个辨别四层和七层比较好的(但不是绝对的)小窍门,“两个凡是”:凡是由操作系统负责处理的就是四层或四层以下,否则,凡是需要由应用程序(也就是你自己写代码)负责处理的就是七层

由于 HTTP 是在 TCP/IP 协议之上的,而 TCP/IP 协议负责底层的具体传输工作,所以 http 在传输方面不用太操心,TCP/IP 会去解决,所以 HTTP 关心的就只有他所传输的报文内容,又因为 HTTP 是“纯文本”的,包括头信息都是 ASCII 码的文本,不用借助程序解析可以直接阅读。

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220321/619a6b063a5e4ced936d156d155f3fed.png?imageView2/0/interlace/1/q/50|imageslim

  • 字段名不区分大小写,例如“Host”也可以写成“host”,但首字母大写的可读性更好;
  • 字段名里不允许出现空格,可以使用连字符“-”,但不能使用下划线“_”。例如,“test-name”是合法的字段名,而“test name”“test_name”是不正确的字段名;
  • 字段名后面必须紧接着“:”,不能有空格,而“:”后的字段值前可以有多个空格;
  • 通用字段:在请求头和响应头里都可以出现;
  • 请求字段:仅能出现在请求头里,进一步说明请求信息或者额外的附加条件;
  • 响应字段:仅能出现在响应头里,补充说明响应报文的信息;
  • 实体字段:它实际上属于通用字段,但专门描述 body 的额外信息。
字段 类型 说明
Host 请求字段 唯一一个 HTTP/1.1 规范里要求必须出现的字段,如果请求头里没有 Host,那这就是一个错误的报文。Host 字段告诉服务器这个请求应该由哪个主机来处理
User-Agent 请求字段 描述发起 HTTP 请求的客户端,服务器可以依据它来返回最合适此浏览器显示的页面
Date 通用字段 表示 HTTP 报文创建的时间,客户端可以使用这个时间再搭配其他字段决定缓存策略
Server 响应字段 告诉客户端当前正在提供 Web 服务的软件名称和版本号
Content-Length 实体字段 报文里 body 的长度,也就是请求头或响应头空行后面数据的长度。服务器看到这个字段,就知道了后续有多少数据,可以直接接收。如果没有这个字段,那么 body 就是不定长的,需要使用 chunked 方式分段传输

https://cdn.xiaobinqt.cn/xiaobinqt.io/20220321/c113e062fccf4d18959dc52d90e59c1b.png?imageView2/0/interlace/1/q/50|imageslim

方式 说明
GET 获取资源,可以理解为读取或者下载数据
HEAD 获取资源的元信息,不会返回请求的实体数据,只会传回响应头
POST 向资源提交数据,相当于写入或上传数据
PUT 类似 POST
DELETE 删除资源
CONNECT 建立特殊的连接隧道
OPTIONS 列出可对资源实行的方法
TRACE 追踪请求 - 响应的传输路径
状态码 含义
1×x 提示信息,表示目前是协议处理的中间状态,还需要后续的操作
2×× 成功,报文已经收到并被正确处理
3×× 重定向,资源位置发生变动,需要客户端重新发送请求
4×× 客户端错误,请求报文有误,服务器无法处理
5×× 服务器错误,服务器在处理请求时内部发生了错误

一些常用状态码说明

status code 说明
301 永久重定向,含义是此次请求的资源已经不存在了,需要改用改用新的 URI 再次访问
302 临时重定向,意思是请求的资源还在,但需要暂时用另一个 URI 来访问。比如,你的网站升级到了 HTTPS,原来的 HTTP 不打算用了,这就是“永久”的,所以要配置 301 跳转,把所有的 HTTP 流量都切换到 HTTPS。 再比如,今天夜里网站后台要系统维护,服务暂时不可用,这就属于“临时”的,可以配置成 302 跳转,把流量临时切换到一个静态通知页面,浏览器看到这个 302 就知道这只是暂时的情况,不会做缓存优化,第二天还会访问原来的地址。
304 Not Modified,它用于 If-Modified-Since 等条件请求,表示资源未修改,用于缓存控制。它不具有通常的跳转含义,但可以理解成“重定向已到缓存的文件”(即“缓存重定向”)
405 不允许使用某些方法操作资源,例如不允许 POST 只能 GET
406 Not Acceptable 资源无法满足客户端请求的条件,例如请求中文但只有英文
408 Request Timeout:请求超时,服务器等待了过长的时间
409 Conflict:多个请求发生了冲突,可以理解为多线程并发时的竞态
413 Request Entity Too Large:请求报文里的 body 太大
414 Request-URI Too Long:请求行里的 URI 太大
429 Too Many Requests 客户端发送了太多的请求,通常是由于服务器的限连策略
431 Request Header Fields Too Large 请求头某个字段或总体太大
500 Internal Server Error 与 400 类似,也是一个通用的错误码,服务器究竟发生了什么错误我们是不知道的。不过对于服务器来说这应该算是好事,通常不应该把服务器内部的详细信息,例如出错的函数调用栈告诉外界。虽然不利于调试,但能够防止黑客的窥探或者分析
501 Not Implemented 表示客户端请求的功能还不支持,这个错误码比 500 要温和一些,和“即将开业,敬请期待”的意思差不多,不过具体什么时候“开业”就不好说了
502 Bad Gateway”通常是服务器作为网关或者代理时返回的错误码,表示服务器自身工作正常,访问后端服务器时发生了错误,但具体的错误原因也是不知道的
503 Service Unavailable 表示服务器当前很忙,暂时无法响应服务,我们上网时有时候遇到的“网络服务正忙,请稍后重试”的提示信息就是状态码 503
  • HTTP 是灵活可扩展的,可以任意添加头字段实现任意功能。
  • HTTP 是可靠传输协议,基于 TCP/IP 协议“尽量”保证数据的送达。
  • HTTP 是应用层协议,比 FTP、SSH 等更通用功能更多,能够传输任意数据。
  • HTTP 使用了请求 - 应答模式,客户端主动发起请求,服务器被动回复请求。
  • HTTP 本质上是无状态的,每个请求都是互相独立、毫无关联的,协议不要求客户端或服务器记录请求相关的信息。