拆解URL

6 阅读3分钟

一、URL 基本结构与组成部分

完整 URL 示例

https://user:pass@www.example.com:8080/path/to/resource?query=param#fragment  
│   │     │     │              │      │              │          │  
│   │     │     │              │      │              │          └─ 片段标识符(Fragment)  
│   │     │     │              │      │              └─────────── 查询参数(Query)  
│   │     │     │              │      └────────────────────────── 路径(Path)  
│   │     │     │              └───────────────────────────────── 端口(Port)  
│   │     │     └───────────────────────────────────────────────── 域名(Domain)  
│   │     └──────────────────────────────────────────────────────── 用户名:密码(身份验证)  
│   └───────────────────────────────────────────────────────────── 协议(Scheme)  

二、各组成部分详解(高频考点)

1. 协议(Scheme)
  • 作用:指定数据传输方式(如 httphttpsftpws);
  • 安全协议httpshttp 的加密版本,通过 TLS/SSL 协议加密数据;
  • 特殊协议
    • file://:访问本地文件系统;
    • mailto::打开邮件客户端(如 mailto:example@domain.com)。
2. 域名(Domain)与 IP 地址
  • 域名结构
    subdomain.example.co.uk  
    │         │     │   └─ 顶级域名(TLD)  
    │         │     └────── 二级域名(SLD)  
    │         └───────────── 主域名  
    └─────────────────────── 子域名  
    
  • 解析流程:浏览器通过 DNS 服务器将域名转换为 IP 地址;
  • 特殊域名
    • localhost(127.0.0.1):本地回环地址;
    • 0.0.0.0:表示所有可用的网络接口。
3. 端口(Port)
  • 作用:标识服务器上的特定服务(默认 http 为 80,https 为 443);
  • 格式域名:端口(如 example.com:8080);
  • 隐藏规则:若端口为协议默认值,可省略(如 https://example.com 省略 443)。
4. 路径(Path)
  • 作用:定位服务器上的资源(类似文件系统路径);
  • 格式
    • 绝对路径:以 / 开头(如 /api/users);
    • 相对路径:省略域名部分(如 users/123);
  • 特殊符号
    • .:当前目录;
    • ..:上级目录;
    • //:协议相对路径(如 //cdn.example.com/js/lib.js)。
5. 查询参数(Query)
  • 格式?key1=value1&key2=value2
  • 编码规则
    • 空格 → %20
    • &%26
    • 中文 → UTF-8 编码(如 张三%E5%BC%A0%E4%B8%89);
  • 用途:向服务器传递数据(如搜索关键词、分页参数)。
6. 片段标识符(Fragment)
  • 作用:标识页面内的特定位置(如 #section2 指向页面中 ID 为 section2 的元素);
  • 特点
    • 仅客户端解析,不发送到服务器;
    • 改变片段不会触发页面刷新,仅滚动到对应位置。

三、URL 编码与解码(高频考点)

1. 为什么需要编码?
  • URL 只能使用 ASCII 字符集,非 ASCII 字符(如中文、空格)需转换为 %HH 格式(HH 为字符的十六进制 ASCII 码)。
2. JavaScript 中的编码/解码方法
方法编码范围典型用途
encodeURI()保留 /:?# 等特殊字符编码完整 URL
encodeURIComponent()编码所有非 ASCII 字符和大部分特殊字符编码查询参数值(如 key=value 中的 value
decodeURI()解码 encodeURI() 编码的内容解码完整 URL
decodeURIComponent()解码 encodeURIComponent() 编码的内容解码查询参数值

示例

const url = 'https://example.com/path?name=张三&age=20';
const encoded = encodeURI(url); // 仅编码非法字符(如中文)
const componentEncoded = encodeURIComponent(url); // 编码所有特殊字符(包括 /、? 等)

console.log(encoded); // https://example.com/path?name=%E5%BC%A0%E4%B8%89&age=20
console.log(componentEncoded); // https%3A%2F%2Fexample.com%2Fpath%3Fname%3D%E5%BC%A0%E4%B8%89%26age%3D20

四、问题

1. 问:URL 中 #? 的区别是什么?

  • ?(查询参数)
    • 用于向服务器传递数据,会随请求发送到服务器;
    • 格式为 ?key1=value1&key2=value2,多个参数用 & 连接。
  • #(片段标识符)
    • 用于标识页面内的特定位置,仅客户端解析,不会发送到服务器;
    • 改变 # 后的值不会触发页面刷新,仅改变浏览器历史记录(如单页应用路由)。
2. 问:如何在 JavaScript 中解析 URL 的各部分?

  • 使用 URL 对象(现代浏览器支持):
    const url = new URL('https://user:pass@example.com:8080/path?query=param#fragment');
    
    console.log(url.protocol); // https:
    console.log(url.username); // user
    console.log(url.password); // pass
    console.log(url.host);     // example.com:8080
    console.log(url.hostname); // example.com
    console.log(url.port);     // 8080
    console.log(url.pathname); // /path
    console.log(url.search);   // ?query=param
    console.log(url.hash);     // #fragment
    
  • 兼容旧浏览器:
    const a = document.createElement('a');
    a.href = 'https://example.com/path?query=param';
    
    console.log(a.hostname); // example.com
    console.log(a.search);   // ?query=param
    
3. 问:URL 编码与解码的底层原理是什么?

  • 编码流程
    1. 将非 ASCII 字符转换为 UTF-8 字节序列;
    2. 每个字节转换为 % 后跟两位十六进制数(如 空格%20)。
  • 解码流程
    1. %HH 格式的字符串还原为字节序列;
    2. 将字节序列按 UTF-8 解码为原始字符。

五、总结

协议定传输,域名找主机,端口定位服务;
路径指资源,查询传参数,片段标位置;
编码避非法,解码还原貌,解析用 URL 对象。