HTTP 协议入门
2024-08-22
HTTP 协议作为互联网的基石(这么说应该不为过),有着复杂且丰富的含义。
完全够写一本书了。《HTTP 权威指南》这本书大概有 720 页。
不过今天这篇文章,不打算深入聊细节,因为绝大多数内容对于普通开发者而言并不重要。如果真的有兴趣,可以去看 RFC 2616 - Hypertext Transfer Protocol — HTTP/1.1🔗。
本文只是一个概述。简单讲讲 HTTP 的前世今生,产生的背景,待解决的问题,以及解决思路。
1. HTTP 概念
HTTP,即超文本传输协议(HyperText Transfer Protocol),是一个应用层协议(Application Layer Protocols)。
所谓应用层,就是直接面向用户,与用户使用的产品息息相关。
HTTP 针对的应用,是浏览器和网页服务器(后面简称服务器)。
HTTP 是 蒂姆·伯纳斯-李🔗 蒂姆·伯纳斯-李 1989 年在欧洲核子研究组织(CERN)发起,当初的设计是用来发布和接收 HTML 页面。当然今天它的使用范围被大大地拓宽了,不仅是 HTML,像 CSS,JavaScript 或者其他多媒体资源都可以基于 HTTP 实现传输。常见的,RESTful (表现层状态转换)设计风格,也是完全基于 HTTP 的。
维基百科上,HTTP 的设计目标十分简洁:
用于分布式、协作式和超媒体信息系统。
看上去十分拗口。
那么回到故事开始的地方。
当初伯纳斯-李爵士开发 HTTP 协议,是为了传输 HTML,HTML 是一种超文本标记语言(HyperText Markup Language)。这种语言起初是用于共享文档。
这是一个非常重要,且十分常见的场景。
- 分布式意味着,每个人都可以访问到内容,而且相互独立,互不干扰
- 协作式意味着每个人的工作内容都可以发布,从而让其他人都看到
- 超媒体信息系统,就是共享的内容,不单是文本,也可以是图片、语音,甚至视频等
于是,一种浏览器/服务器(C/S)架构被设计出来。
服务器是中心化的,所有浏览器都需要与它通信,传输的内容是 HTML。
通信协议,就是 HTTP。
距今(2024 年),HTTP 已经演进出 5 个版本
- HTTP/0.9,已经废弃
- HTTP/1.0,第一个在通信中指定版本号的 HTTP 协议版本
- HTTP/1.1,优化上一个版本,使用广泛
- HTTP/2,当前版本,于 2015 年 5 月作为互联网标准正式发布
- HTTP/3,最新版本,于 2022 年 6 月 6 日标准化,通过 UDP 使用 QUIC 协议传输(可见,HTTP 并非与 TCP 绑定,只要能实现可靠传输,并不限制传输层协议)
不同版本的网络流量,Cloudflare Radar🔗 上有统计。
2. HTTP 工作原理
HTTP 本质是一组协议(Protocol),所谓协议,就是通信双方约定好的一种沟通手段。
语言,文字,都可以理解为一种协议。
只不过,HTTP 是用于浏览器和服务器之间交流的。
传输的内容并不复杂,就是一大段有结构的文本,分为 header 和 body 两部分。header 里放的是 body 的描述信息。
比如,使用 curl
查看本网站:
所以,HTTP 的通信内容是自解释的。看 header,很清楚地知道内容是什么。
由于 HTTP 本身是明文传输,传输的安全性,依赖底层的传输层协议,因此从这个角度看,HTTP 相当精简。这也符合计算机网络中的分层设计理念:每一层的协议,只需要做好当前层该做的。
2.1 通信主体
HTTP 的通信双方,是浏览器和服务器。
服务器是中心化的。虽然有时为了保证服务高可用,会采用冗余部署,但从用户视角看,服务器只有一个。服务器的最大作用,就是存储和响应用户的资源请求。每个资源都有一个唯一标识,叫做统一资源标识符(Uniform Resource Identifiers,URI)。
浏览器是分布式的,每个用户都可以通过浏览器,访问,甚至修改服务器上的资源。
2.2 协议内容
一次 HTTP 请求,包含两个部分:Request(请求)和 Response(响应)。
请求的内容包含:
- 请求行
- 请求头
- 空行
- 其他消息体
响应的内容包含:
- 状态行
- 响应头
- 空行
- 响应体
结构很清楚。
请求行和状态行都只有一行,是对行为的极简概述。请求头和响应头则涵盖更细节的描述,但是长度不确定。不过好在有空行标记边界,这样就可以和实际内容区分开。
依然用 curl
测试。
2.3 安全性
基于 HTTP,有个超文本传输安全协议(HyperText Transfer Protocol Secure, HTTPS)。名字看着挺厉害,其实就是 HTTP over TLS,本质还是 HTTP,只不过传输层用的是 TLS,一种加密通信层。
简单来说,就是协议内容还是 HTTP,但是加解密借助 TLS。
主要目的,是提供服务器的身份认证(避免访问到冒牌网站),数据交换的隐私与完整性(只有通信双方知道通信内容,第三方不可见)。
3. HTTP 启示
大家平时接触到的形形色色的产品,网站也好,APP 也罢,背后庞大的数据交互,都由 HTTP 承载。
可见,这是一个相当通用,且相当健壮的协议。自从 20 世纪 90 年代被发明以来,不断更新,历久弥新,很了不起。
当然,核心的设计理念,没有发生太大变化。
我大致总结出三点:简单,可扩展,无状态。
HTTP 协议只有两种类型,请求和响应。内容也是结构化的,但不像 JSON 那样冗长,十分精简,一行一行排列。且都是明文,不仅对于机器可读,对开发者也很友好,容易定位错误。
HTTP 内容虽然有结构,但是结构内容可以不断追加。比如,增加新的请求方法,增加 header 字段等,兼容性也容易得到保障。
无状态,我认为是 HTTP 设计中最精妙的部分。HTTP 认为每一次请求都是独立的,没有上下文,没有状态需要维护。就像计算机领域中的纯函数,干净,纯粹,没有副作用。没有需要维护的状态,犯错的机会就少了。
4. 总结
HTTP 协议很简单,相关的 RFC 文件也不大。
不过要设计出这种简单的协议,并不是一件容易的事。
或者换句话说,简单只是表象。简单的背后,有着极为复杂的一面,对事物的深刻洞察,对问题的系统思考,对各种权衡的折衷。
可见,简单,有时候也不简单。
(完)
参考
- 本文作者:Plantree
- 本文链接:https://plantree.me/blog/2024/intro-to-http-protocol/
- 版权声明:所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
最后更新于: 2024-11-20T09:44:17+08:00