URL 结构与百分号编码速查
一个 URL 拆开是七个部分、哪些字符必须转义、中文地址为什么变成一长串百分号,以及 URL 到底有没有长度限制。
URL 是互联网上最常被看见、却最少被完整理解的东西。它由若干有明确语义的部分拼成,每一部分各自有转义规则——这也是「同一个地址在浏览器、日志、后端框架里长得不一样」的原因。
理解它有一份很实在的收益:参数该放查询串还是路径、锚点为什么后端读不到、中文为什么变成 %E4%B8%AD、接口报「URL 过长」该怎么改,这些问题都能自己回答。下面先拆结构,再讲编码规则。
1URL 的七个组成部分
以 https://user:pw@www.example.com:8443/a/b?x=1&y=2#top 为例,各部分的名称与作用如下。
| 部分 | 示例 | 说明 |
|---|---|---|
| 协议 Scheme | https | 用什么协议访问。常见有 http、https、ftp、file、mailto |
| 用户信息 Userinfo | user:pw | 已废弃的写法,凭证放在 URL 里会留在日志中,不应再用 |
| 主机 Host | www.example.com | 域名或 IP,是 URL 中唯一必需(在 http/https 下)的部分 |
| 端口 Port | 8443 | 省略时用协议默认值:http 是 80,https 是 443 |
| 路径 Path | /a/b | 资源在服务器上的位置,层级用 / 分隔 |
| 查询 Query | x=1&y=2 | 以 ? 开始,& 分隔多个键值对。用于筛选、分页、搜索词 |
| 锚点 Fragment | top | 以 # 开始。**只在浏览器内生效,不会发送给服务器** |
锚点不发给服务器这一点很实用:如果用锚点传参数,后端永远拿不到;但反过来,用锚点做页面内定位或前端路由,就不会污染服务端的访问日志,也不会影响缓存命中。
2哪些字符必须转义
URL 里的字符分成三类:可以直接出现的、有特殊含义必须转义的、以及可以出现但不建议出现的。转义的写法是 % 加两位十六进制(即该字符 UTF-8 字节的十六进制值)。
| 分类 | 字符 | 处理方式 |
|---|---|---|
| 未保留字符(可直接用) | A-Z a-z 0-9 与 - . _ ~ | 无需转义,出现任何场合都安全 |
| 保留字符(有语法含义) | :/?#[]@ 与 !$&'()*+,;= | 作为分隔符使用时不转义;作为普通数据时必须转义 |
| 必须转义 | 空格、中文、"、<、>、` `、\、^、{|}` 等 | 统一转义,如空格转成 %20 |
| 不安全字符 | 控制字符、换行、制表符 | 一律转义,出现在 URL 中通常说明数据未做处理 |
3中文与空格:实际会变成什么
中文并不是被「翻译」了,而是先按 UTF-8 编码成字节,再把每个字节写成百分号形式。所以一个汉字通常对应三个 %XX。
| 原始内容 | 转义结果 | 说明 |
|---|---|---|
中 | %E4%B8%AD | UTF-8 下「中」是 3 字节,所以有 3 个 %XX |
中文 | %E4%B8%AD%E6%96%87 | 6 个字节,6 个 %XX |
| 空格(路径中) | %20 | 标准写法 |
| 空格(查询串中) | + 或 %20 | + 表示空格只适用于 form-urlencoded 场景,路径中必须用 %20 |
# | %23 | 不转义会被当成锚点起始符,导致后面的内容全被截断 |
& | %26 | 作为参数值出现时必须转义,否则会被切断成新参数 |
| 中文域名 | xn--fiq228c.cn | 国际化域名先转成 Punycode 再解析 |
「参数值里带 `&` 或 `=` 却忘了转义」是最常见的参数解析 bug:看起来是一个参数,服务端却读到了两三个。凡是把用户输入直接拼进 URL 的地方,都要先做一次编码。
4URL、URI、URN 的关系
三个词经常被混用。严格来说,URI 是最大的集合,URL 和 URN 都是它的子集:URL 负责定位(在哪),URN 负责命名(叫什么)。
- URI
- 统一资源标识符,泛指「能标识一个资源的东西」,是 URL 与 URN 的统称
- URL
- 统一资源定位符,指出了「怎么找到它」,日常说的网址就是 URL
- URN
- 统一资源名称,只给资源一个持久名字,不说明怎么获取,实际应用很少
- 日常用法
- 写代码时字段名常叫
uri(含义更宽),实际内容基本是 URL。做技术文档区分时,严格写 URL 更准确 - 路径与查询的取舍
- 资源标识(谁)放路径
/users/123,筛选与排序(怎么取)放查询?page=2&sort=desc。这样缓存与日志分析都更清晰
5URL 有长度限制吗
规范本身没有规定 URL 的最大长度,限制来自具体的实现。所以「URL 太长」是一个工程问题,不是协议问题。
- 规范层面
- RFC 3986 未规定长度上限,任何长度理论上都是合法的
- 浏览器层面
- 现代浏览器支持到数万字符;早年 IE 的 2083 字符限制已经成为历史,但仍常被引用
- 服务器层面
- 才是真正的瓶颈。Nginx 默认单个请求行与请求头缓冲区为 8KB 左右,超过会返回
414或431 - CDN 与网关
- 多数 CDN 对请求行也有类似限制,且不同厂商数值不同,迁移时容易踩
- 应对方式
- 长参数改用 POST 请求体传递;批量 ID 改用逗号分隔而不是重复键;分页参数不要塞进路径;确实需要超长内容的场景改用服务端生成的短标识
看完就能用的站内工具
全部工具总览 →输入任意URL,自动拆分协议、域名、端口、路径、参数、锚点,支持批量解析、参数删除、URL编码解码和CSV导出
URL编码 - URL 加密与解密,编码特殊字符,处理中文路径
在线GET请求参数转JSON工具,将URL查询字符串解析为JSON对象,支持嵌套对象和数组结构还原
在线JSON转GET请求参数工具,将JSON对象转换为URL查询字符串,支持数组格式、变量名风格切换、URLEncode编码
将中文/英文标题转换为SEO友好的URL别名Slug,支持自定义分隔符、中文转拼音、逐行批量生成、实时预览
关于「URL 结构与百分号编码速查」的常见问题
URL 里的锚点(#后面那段)后端能收到吗?
不能。按规范,锚点部分只在客户端(浏览器)内使用,发起请求时会被完全去掉,服务器端根本看不到。所以想用 # 传参数给后端是行不通的。反过来,如果某个信息只与前端展示有关(页面内定位、前端路由状态、滚动位置),放在锚点里反而是好选择——它不会污染服务端日志,也不会影响缓存键。
为什么中文参数在地址栏里变成了一串 %E4%B8%AD?
这是百分号编码(也叫 URL 编码)。URL 只允许出现一部分 ASCII 字符,其它字符必须先按 UTF-8 编码成字节,再把每个字节写成 % 加两位十六进制的形式。「中」在 UTF-8 下是 3 个字节(E4 B8 AD),所以编码后就是 %E4%B8%AD。这不是乱码,而是标准写法,属于同一套规则对空格(%20)、井号(%23)的处理方式。
URL 最大能有多长?
协议规范没有规定上限,限制来自实现。服务器端通常是真正的瓶颈:Nginx 默认的请求行与请求头缓冲区合计约 8KB,超出会返回 414(URI Too Long)或 431(请求头过大);各类 CDN 与网关也各有自己的限额。浏览器侧现代版本支持到数万字符,早年 IE 的 2083 限制已不适用。所以处理长参数应优先改用 POST 请求体,而不是试图把 URL 拉长。
把参数放在路径里还是查询串里?
一个简单的判断标准:这个信息是「资源的身份」还是「取资源的方式」。身份放路径,例如 /users/123、/articles/how-to-xxx;取法放查询串,例如 ?page=2&sort=desc&q=关键词。这样做的直接好处是缓存与日志分析都更清晰——同一资源的不同筛选条件可以被识别为同一类请求,而资源本身的地址保持稳定,页面改版也不会影响已收录的链接。
继续查:相关内容
全部速查 →内容说明:本页速查数据由本站自行整理,事实性内容以对应官方规范与文档为准,未复制第三方速查表或百科的表述。数据最后核对日期:2026-10-05。若发现错误或已更新的标准,欢迎通过页脚反馈入口告知。
速查在线工具箱