📘 第一章 了解Web及网络基础
📄 一句话概括

Web 的出发点不是「上网」,是让散在各处的文档互相引用。 超文本(hyperlink)是它的灵魂,HTTP 只是搬运它的车。

📝 本节和前面几节的关系

上一节拆了一次访问的环节。 这一节退到最源头回答一个问题:为什么这套东西长成了「一份文本带一堆链接」的样子。

一、先有超文本,后有 Web

1989 年,CERN 的 Tim Berners-Lee 要解决一个很具体的麻烦:实验室里几十种文档系统、几十套机器, 彼此的文档谁也读不了谁。 他的方案不是统一文档格式,而是只统一「怎么指过去」——每份文档里写一个地址, 点一下就能跳到另一份。这就是超文本。 所以 Web 从出生起就有三个部件:地址(URI)、传输(HTTP)、内容(HTML)。 三者缺一不可,但只有「地址」是骨架。

二、链接是唯一必须的语法

下面这个 Demo 把一份最小的 HTML 送到服务端再拿回来,数出里面有两条 href: 一条相对路径 /b.html,一条绝对地址。 正文本身 214 字节,两条链接加起来不到 40 字节。 但把这 40 字节去掉,它就退化成一份普通文档——Web 的全部威力在这 40 字节里。 顺带看到服务端回的三个首部:Content-Type、Content-Length、Connection。 其中 Content-Type 是「超文本能显示」的前提:少了它,浏览器只能把这堆标签当纯文字铺出来。 内容要能被解释,必须先声明自己是什么。

三、共享的前提是「谁都能实现」

Web 能赢过同期那些更精致的系统(如 HyperCard、Gopher),关键不在功能多, 而在规格公开、实现免费:服务端只要会解析一行 GET,客户端只要会渲染标签,两边就能通。 这条原则后来反复出现:HTTP/1.1 能被所有语言实现,所以它统治了二十年; HTTP/2 把二进制帧格式写进标准、要求 TLS,实现门槛抬高,但因为在浏览器里,还是推开了。

四、动手 Demo:一份最小超文本:数出它的链接

把 HTML 原文发到本机服务端,再抓回服务端的原始响应,拆出状态行、首部、正文, 然后从正文里把 href 一条条找出来。

page = (u"<h1>我的主页</h1>"
        u"<p>去看 <a href='/b.html'>另一页</a>,"
        u"或者去 <a href='http://example.com/'>外面</a>。</p>")
H.SINK.raw.clear()
with H.server() as port:
    raw = H.send(port, REQ11)
status, headers, body = H.split_response(raw)
# 数 href
links = []
i = 0
while True:
    a = page.find(u"href='", i)
    if a < 0:
        break
    b = page.find(u"'", a + 6)
    links.append(page[a + 6:b])
    i = b + 1

实跑输出:

--------------------------------------------------------------------
超文本:一份文本加几根指向别处的线
--------------------------------------------------------------------
  客户端发出                 64 字节
  服务端回                   138 字节
  状态行                     HTTP/1.1 200 OK
    Content-Type             text/html; charset=utf-8
    Content-Length           40
    Connection               close
  正文里的链接               2 条
    /b.html                  相对路径
    http://example.com/      绝对 URI
  正文本身只有 214 字节,价值在 href 上——这就是「超文本」和普通文本的全部差别。
  服务端必须告诉客户端「这是哪种文本」,靠 Content-Type;少这一行,浏览器只能当纯文本显示。

客户端发出 64 字节、服务端回 138 字节——一次完整往返的字面量就在这两行。 打开任何一个抓包工具,看到的也是这个形态,只是多了 TCP/IP 的头。 正文里的链接 2 条,一条相对、一条绝对。 相对路径要结合当前页面的地址才能算出完整地址,这是 1.7 节讲 URI 相对引用时的伏笔。

30 秒实验

  1. 把 href='/b.html' 改成 href='b.html'(去掉开头的斜杠),想一想:页面在 /a/c.html 时, 这两种写法指向的地址一样吗?
  2. 在响应里删掉 Content-Type 那行,把返回的字节存成 .html 用浏览器打开,看中文会不会变成乱码。
  3. 把正文里的 href 全部换成纯文本,再想想这份文档还能不能叫「超文本」。

常见误区

  1. 「Web 就是互联网」——互联网比 Web 早二十年,Web 只是跑在它上面的一种应用。
  2. 「超文本就是带样式的文本」——样式是 CSS 的事,超文本强调的是可跳转。
  3. 「HTML 是 Web 的核心」——地址才是。没有 HTML 还能传 JSON,没有 URI 就没有「跳过去」这件事。
自测三问(点开对答案) 1. Web 的三个基本部件是什么? —— URI(地址)、HTTP(传输)、HTML(内容)。三者的共同目标是「文档能互相引用」。 2. 为什么 `Content-Type` 必不可少? —— 它告诉客户端这段字节该怎么解释。缺了它,浏览器只能猜或当纯文本处理。 3. CERN 当初要解决的具体问题是什么? —— 不同机器、不同文档系统之间无法互相阅读。解法不是统一格式,而是统一寻址。

有了寻址和超文本,Web 就开始长了。下一节看它长了二十年长成了什么形状。

相关笔记