Web 如何工作
网络并不存在,当人们以某种方式联系起来就形成了网络
C/S 架构
为了向人们展示信息(商品列表,博客,视频等)至少要经过以下几步
- 将信息存储在计算机上
- 把这台计算机暴露在公共空间
- 当有人想要获取这些信息时,他也必须把自己暴露在公共空间,并指定资源在哪里
- 信息开始传输
第一步中的计算机被称为服务器(Server), 第三步中的计算机被称为客户(Client); 他们所处的环境(公共空间)被称为网络,要传输的信息被认为是资源;就这样我们建立起了信息传输的基本架构: C/S 架构。
有些人可能会提到 B/S 架构,也即 Browser/Server 架构。但其实浏览器(Browser)只是 Client 的一种, 人们不单单可以使用浏览器来获取服务器上的信息。事实上,黑客电影中的天才们大多使用只能展示纯文本的终端获取信息,这个终端其实也是 Client。
IP 地址
发信和送信双方进行信息传递的公共空间被称为网络,网络提供了发送和获取资源的一切中间条件。
和现实中的快递一样,一个强制的条件就是收发件双方都必须填好自己的地址。而且这个地址必须是唯一的且精确的,如果你在收件人一栏写上北京市显然就不合适。
在 Web 中每台计算机都被赋予一个独一无二的地址,这个地址被称为 IP 地址。目前广泛使用的版本是 IP V4,它规定每个 IP 地址由 32 位二进制数值组成,每 8 位为一组分为 4 组,以英文句号隔开。比如:159.247.203.8 就是一个 IP 地址的十进制表示。
DNS
IP 地址并不容易人们记忆,人们发明了域名来代替 IP 地址。当人们需要使用谷歌搜索时,只需要记住谷歌的域名是 google.com 就够了。计算机使用 IP 地址,而人类想要使用域名,如果能轻松的把域名转为 IP 地址就可以了。这部分工作叫 DNS (Domain Name Service), Web 上有无数计算机在执行着这简单确极为重要的工作,这些计算机被称为 DNS Server。
HTTP 协议
有了 IP 地址和 DNS 我们能够定位到通信双方,现在可以开始交换信息。但发送和接收的信息如何解释和处理并没有解决。比如一段普通中文文本,发信方使用 UTF-8 进行编码为二进制字符串,收信方如何知道这串字符的编码方式是 UTF-8 呢?在不知道这些信息的情况下,收信方很可能使用 ASCII 码进行解码,这就会造成乱码的现象发生。
很显然,收发信双方需要某种约定,发信方在发信时应该说明该资源的类型。这种约定被称为协议,在 Web 中,最常用的是 HTTP 协议, 它确定了发送和接收信息的规范。信息的类型只是规范的一小部分,只要参与通信的双方都遵守协议,那么信息就很容易被接收方理解。
HTML - 结构化标签语言
试想一篇博客,里面可能有各种格式化的信息:文章标题,章节标题,段落;大体的结构可能是:
标题
- 观点 1
- 段落 1
- 段落 2
- 观点 2
- 段落 3
- 段落 4
如果需要把这些信息展示给读者,最重要的工作是把结构清晰地展现出来;现在的通用标准是使用 HTML。
HTML(HyperText Markup Language) 是一种结构化的显示语言,主要有以下 3 种机制:
- 在一个页面可以通过链接跳转到另一个页面,这种链接被称为超文本(HyperText)
- 通过标签(Tag)对不同类型的信息进行标记(Markup),这种标签也被称为页面元素
- 标签之间通过嵌套表示层级关系,从而表示页面的结构化信息
以上文章用 HTML 可以表示为:
<div>
<h1>标题</h1>
<section>
<h3>观点1</h1>
<div>
<p>段落1</p>
<p>段落2</p>
</div>
</section>
<section>
<h3>观点2</h1>
<div>
<p>段落3</p>
<p>段落4</p>
</div>
</section>
</div>
如果 Client 知道 HTML 的语法,那么 Client 就知道这片文章的结构,剩下的工作就是将这种结构信息用样式渲染出来。
JavaScript - 为 Web 带来动态
HTML 只是一种显示语言,这决定了 HTML 是静态的。的确,HTML 里面的表单元素比如 <input> <select> <button>
提供了一些交互,用户可以进行输入选择点击等操作。但 HTML 最初是没有这些标签的,当时的设想很简单:用一种结构化的方式显示信息并通过链接将 Web 上的文档联系起来。第一版 HTML 甚至没有提供按钮,更别提输入框和下拉列表了。事实上,只有在 JavaScript 被发明才推出了这些交互性标签,因为交互的基础是 JavaScript 的存在。
所有的主流浏览器都有理解和执行 JavaScript 的能力,打开浏览器的控制台立即就可以编写并执行 JavaScript 代码,没有其他语言的环境设置要比这还要简单了。
懒人的第一行代码:console.log("hello world")
DOM - 为 HTML 建模
HTML 简单直观,但却没有提供一种可编程的方式来控制它。要实现动态,必须将 HTML 抽象为某种可以直接被 JavaScript 利用的模型。
计算机科学早已经为我们提供了层级关系对应的数据结构 - 树。每个标签对应树中的一个节点,每个节点都是一个 JavaScript 对象。当然整颗树本身也是个 JavaScript 对象,这个对象被称为 DOM (Document Object Model)
HTML 被建模为 JavaScript 对象,我们就可以直接对其进行 CRUD 操作了。之后浏览器会响应 DOM 的改变,进而更新 HTML 并渲染出新的页面出来。
Web API - 通用 JavaScript 接口
其实 DOM 就是 Web API 的一部分,但 Web API 还包含其他内容,以下是一些例子:
- fetch:提供网络请求能力
- html drag & drop: 拖拽页面元素
- history: 控制浏览器的会话历史
- WebRTC: 提供点对点通信能力,通常用于实时视频或者音频通话
- WebSocket: 实现浏览器和服务器之间的双向通信
- Web GL: 3D 图形渲染
- Canvas: 2D 图形渲染
以上是 Web 能正常工作所必须的基础设施。当然还有其他方面没有谈到,比如 CSS |浏览器的渲染过程| HTTPS |前端框架等。以后我会写博客专门介绍这些内容。