🕸️ 第一章 Web技术基础知识
📄 一句话概括

URL 是网页在网上的门牌号,它由七块拼成;其中最要紧的"域名"那一块,又是一串从右往左、一级比一级大的层级——这套层级叫 FQDN。

📝 本节和前面几节的关系

上一篇说浏览页面第一步是"报地址",并且强调地址必须精确。这一篇就把这个地址拆开,一块块看它是什么。上一篇还留了一句话——"门牌可能难看,但它精确"——精确体现在哪,读完这一篇就清楚了。地址里的域名怎么变成机器认得的 IP,前一门课讲过(网络的电话簿),本篇只讲"地址本身怎么拼",不重复那一段。

一、一个 URL 由七块拼成

拿一个"要素最全"的地址来开刀:

https://[email protected]:8443/shop/item?id=42&sort=asc#reviews

它看着乱,其实七块各管一件事,顺序固定、分隔符固定:

块 值 干什么用
scheme https 用什么协议去取
userinfo user 身份(早已不推荐写在这里)
host www.example.co.jp 去哪台机器
port 8443 敲哪扇门(不写就用默认)
path /shop/item 要机器上的哪一份
query id=42&sort=asc 附带的条件
fragment reviews 页面内部的位置

记住分隔符,就能一眼读地址:

二、两个最容易忽略的细节

第一,port 处通常什么都没有。 因为每种协议都有自己的默认门牌号——http 默认 80,https 默认 443。不写就等于用默认。所以 https://example.com 和 https://example.com:443 是同一个地方。只有用了非默认端口(比如自己搭的测试服务器 8080),才必须写出来。

第二,# 后面那一段根本不会发给服务器。 它是给浏览器自己看的——用来在已经打开的页面里滚到某个位置。换句话说,a.html#x 和 a.html#y 从服务器那儿取回来的是同一份文件,只是滚到的地方不同。这也是为什么单页应用(比如文档站)能靠 # 切换不同的"页面",却不用每次都请求服务器。

三、域名那一块:从右往左,一级比一级大

host 那一段(www.example.co.jp)看着像一串单词,其实是一片分层结构。读它的方向是从右往左:

层 值 是什么
主机名(最左,最具体) www 这台机器在这家公司里的名字
注册的机构名 example 这家公司注册的名字
类别 co 这一级表示"公司"
顶级域(最高一级) jp 属于哪个国家或类别

为什么从右往左读? 因为越往右越稳定、越大。最右边的 jp 是国别(日本),往左 co 是类别(公司),再往左 example 是具体哪一家,最左边的 www 是这家公司的某台机器。

这样设计的好处是"分权":管 jp 的机构只需要知道 co.jp 下面有哪些注册的名字,不用管每家内部怎么再分——每一级只负责自己那一层。这就是域名能扩展到全球的原因。

写全的这套名字,正式叫 FQDN(完全限定域名)。规矩上有两个上限:整串最长 255 个字符,每一层最长 63 个字符。

四、动手 Demo:把一个 URL 拆开

下面这个 Demo 用几行代码,把上面那个地址真拆一遍,再把域名逐层列出来。

def parse(u):
    scheme = u.split("://")[0]
    rest = u.split("://", 1)[1]
    frag = rest.split("#", 1)[1] if "#" in rest else ""
    rest = rest.split("#", 1)[0]
    query = rest.split("?", 1)[1] if "?" in rest else ""
    rest = rest.split("?", 1)[0]
    hp = rest.split("/")[0]
    return scheme, hp, rest[len(hp):] or "/", query, frag

print(parse("https://[email protected]:8443/shop/item?id=42&sort=asc#reviews"))

实跑输出:

--------------------------------------------------------------------
D4  什么是 URL:拆开看,它是七块拼起来的
--------------------------------------------------------------------
  拿一个最复杂的例子开刀:
  https://[email protected]:8443/shop/item?id=42&sort=asc#reviews

  ----------------------------------------------------------------------------------------
  块            值                                干什么用
  ----------------------------------------------------------------------------------------
  scheme        https                             用什么协议去取
  userinfo      user                              身份(早已不推荐写在这里)
  host          www.example.co.jp                 去哪台机器(域名)
  port          8443                              敲哪扇门(不写就用默认)
  path          /shop/item                        要机器上的哪一份
  query         id=42&sort=asc                    附带的条件
  fragment      reviews                           页面内部的位置(不发去服务器)

  其中 host 那一块,本身又是一串层级——域名从右往左,一级比一级大:

    www                       (主机名,最左,最具体)
    example                   (注册的机构名)
    co                        (类别)
    jp                        (顶级域,最高一级)

  这个主机名一共 4 层,写全了就称为 FQDN(完全限定域名)。
  规则上说:整串最长 255 字符,每一层最长 63 字符。
  非英文域名要先转成 punycode 才能上路,例如 cafe.com 会变成 xn--caf-dma.com。

读这个输出:最该记住的是最后两行。非英文域名不能直接上路——因为域名系统只认英文和数字,所以中文、日文、带重音的域名要先转成一种叫 punycode 的写法(开头是 xn--)。你在地址栏里看到的是好读的样子,实际去解析的是转出来那串。

五、⚠️ 2026 现状

教材 2024 年出版,URL 的规矩今天有一处重要的正名:

30 秒实验

随便打开一个网页,把地址栏里的地址抄下来,做三件事:

  1. 找分隔符:找到 ://、?、#,各划一条线,看看哪一段是哪一块。
  2. 看有没有端口:你会发现通常没有——那就说明它用的是默认端口(http 是 80、https 是 443)。
  3. 看域名:看最右边那一层是什么(com、cn、jp……),再往左一层,读出"这是哪个国家的哪一类机构"。

然后想一想:如果这一页里点了另一个内部链接,地址里哪几块变了、哪几块没变?

常见误区

  1. 错误:地址里写了 #something,服务器就会收到它。——纠正:# 后面那一段从来不会发给服务器。它是浏览器自己用的,用来在页面内定位。所以从服务器的角度看,a#x 和 a#y 是同一个请求——这也是它能被前端拿来做"假翻页"的原因。

  2. 错误:域名是从左往右读的,www 最大。——纠正:正好相反,从右往左读、一级比一级大。最右边是顶级域(jp),最左边是具体的主机名。记反了会导致你看不懂"为什么改个公司名要动中间那一段"——因为注册的是中间那段,www 只是它底下的一台机器。

  3. 错误:URL 就这样用吧,改了也没什么。——纠正:地址是门牌,改了就找不到了。网站改版把旧地址一改,别人收藏的链接、搜索引擎记的地址全部失效。所以正规做法是旧地址自动跳转到新地址——这也是为什么 URL 一旦发布,通常就不再改动。

  4. 错误:中文域名很好,直接写就行,不用管什么 punycode。——纠正:好写不等于好解析。域名系统只认英文和数字,中文域名必须转成 xn-- 开头的 punycode 才能实际使用。你在地址栏里看到中文,是浏览器替你转的——直接拿它去别的程序里用,往往就行不通。

自测三问(点开对答案) 1. `https://shop.example.com` 和 `https://shop.example.com:443/` 是同一个地方吗? —— **是**。`https` 的默认端口就是 443,不写等于用默认;路径不写时默认是 `/`。**所以这两个地址指向同一个资源**。理解这一点,你在配置服务器和排错时就不会被"地址看起来不一样"骗到。 2. 为什么域名要从右往左读,一层一级往上? —— 因为**越往右越稳定、越大**:`jp` 是国别,全日本共用;`co` 是类别;`example` 才是具体哪一家。这样设计让**每一级机构只负责自己那一层**——管 `jp` 的不需要知道日本每家公司内部怎么分。**分层是为了分权,分权是为了能扩展到全球**。 3. 单页应用靠什么做到"切换页面却不重新请求服务器"? —— 靠 **`#` 那一块**。因为 `#` 后面的内容**根本不会发给服务器**,所以浏览器可以在不发起新请求的情况下,根据它来改变页面上显示的内容。**代价是真正的地址(`?` 之前的那些)没变**,所以搜索引擎收录时可能碰到麻烦——这也是前端工程师要专门处理的问题。

相关笔记