什么是百分号编码
URL里可以直接书写的字符只有英文字母、数字和少数符号。中文、空格、表情符号,以及在URL里本来有特殊含义却想当作普通数据使用的符号,都需要先转成UTF-8字节, 再把每个字节写成"%"加两位十六进制数,这就是百分号编码(通常也叫URL编码)。例如"你"在UTF-8中占3个字节(E4 BD A0),编码后是 %E4%BD%A0;空格是1个字节(20),编码后是 %20。 在地址栏输入中文也能正常搜索,是因为浏览器在发送请求前悄悄做了同样的转换。
规则出自RFC 3986,把字符分成三类:非保留字符(字母、数字和 - . _ ~)永远不需要编码;保留字符在URL语法中有分隔作用,包括 : / ? # [ ] @,以及用于各部分内部的 ! $ & ' ( ) * + , ; =,当你想把它们当作数据而不是分隔符时必须编码;其余字符则一律要编码。
encodeURIComponent与encodeURI的区别
JavaScript提供两个内置函数,选错是链接失效的常见原因。encodeURIComponent用于"一份数据",比如一个查询参数值或路径中的一段,它只保留字母、数字和 - _ . ! ~ * ' ( ),其余全部转义。encodeURI用于结构已经完整的地址,它还会保留 ; , / ? : @ & = + $ #,只转换中文、空格等字符。 假如搜索词是"A&B",直接放进查询串,&会被当成参数分隔符,值就被截断了,因此参数值必须使用encodeURIComponent,这也是本工具默认采用参数值模式的原因。
| 字符 | encodeURI | encodeURIComponent | 严格(RFC 3986) | URLSearchParams |
|---|---|---|---|---|
空格 ( ) | %20 | %20 | %20 | + |
斜杠 (/) | / | %2F | %2F | %2F |
问号 (?) | ? | %3F | %3F | %3F |
与号 (&) | & | %26 | %26 | %26 |
等号 (=) | = | %3D | %3D | %3D |
井号 (#) | # | %23 | %23 | %23 |
加号 (+) | + | %2B | %2B | %2B |
百分号 (%) | %25 | %25 | %25 | %25 |
冒号 (:) | : | %3A | %3A | %3A |
方括号 ([) | %5B | %5B | %5B | %5B |
单引号 (') | ' | ' | %27 | %27 |
感叹号 (!) | ! | ! | %21 | %21 |
波浪号 (~) | ~ | ~ | ~ | %7E |
上表是页面构建时用真实函数算出来的。注意:encodeURIComponent会保留 ! ' ( ) *,而RFC 3986把它们归为子分隔符而非非保留字符,需要严格一致时请打开严格模式; 另外encodeURI会把 [ 和 ] 也转义。
空格到底是%20还是+
在一般的URL规则里,空格就是 %20。把空格写成 + 属于另一种格式 application/x-www-form-urlencoded,常见于HTML表单提交,这种格式里真正的加号要写成 %2B。decodeURIComponent不会把+还原成空格,所以 a+b 解码后仍是 a+b;要还原表单格式的数据,请勾选上面的选项。拿不准时用 %20 最稳妥。
字节数与长度
| 输入 | 字符数 | UTF-8字节数 | encodeURIComponent | encodeURI |
|---|---|---|---|---|
| 你 | 1 | 3 | %E4%BD%A0 | %E4%BD%A0 |
| 你好世界 | 4 | 12 | %E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C | %E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C |
| 北京欢迎你 | 5 | 15 | %E5%8C%97%E4%BA%AC%E6%AC%A2%E8%BF%8E%E4%BD%A0 | %E5%8C%97%E4%BA%AC%E6%AC%A2%E8%BF%8E%E4%BD%A0 |
| café | 4 | 5 | caf%C3%A9 | caf%C3%A9 |
| 😀 | 1 | 4 | %F0%9F%98%80 | %F0%9F%98%80 |
| 100% | 4 | 4 | 100%25 | 100%25 |
| https://example.com/search?q=a&b=c | 34 | 34 | https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Da%26b%3Dc | https://example.com/search?q=a&b=c |
每个字节要写成3个字符,所以一个汉字变成9个字符,一个表情符号变成12个字符,含大量中文的网址会明显变长。最后一行说明了差别:整理完整地址用encodeURI; 把一个网址整体作为另一个网址的参数传递(例如跳转地址)时,则要用encodeURIComponent。
计算示例
示例1。"你好世界"编码后是 %E4%BD%A0%E5%A5%BD%E4%B8%96%E7%95%8C,接在 https://example.com/search?q= 后面就是完整的搜索链接。
示例2。"100%"编码后是 100%25。百分号本身也要编码,否则直接拿去解码会因为格式错误而失败。
示例3(重复编码)。"a b"编码一次是 a%20b,再编码一次变成 a%2520b。如果解码后结果里仍有%XX,说明被编码了两次,再解码一次即可。
错误与局限
- 解码出错。常见原因是%后面不足两位十六进制数、字符串在中途被截断,或字节不是UTF-8。早期网站使用GBK编码的链接(例如"你"在GBK中是
%C4%E3)无法按UTF-8读取,会报错。 - 不成对的代理项。残缺的表情符号无法编码。
- 长度限制。处理本身很快,但浏览器、服务器和代理对URL长度有限制,一般建议整条URL控制在约2000个字符以内。
- 不是URL解析器。本工具只做字符串转换,不拆分协议、主机、路径,也不转换中文域名(Punycode)。
隐私与安全
转换只使用浏览器内置函数,不发出网络请求,也不保存内容。但编码不是加密,任何人都能立刻还原;放进URL的内容还可能出现在浏览历史、服务器日志和来源信息中,所以不要把密码、令牌或个人信息放在查询参数里。 遇到来历不明的长链接,可以先解码看看真实的目标域名,有助于识别钓鱼网站。
使用建议
常见用途包括手工拼接接口地址、查看日志里带%的字符串、在统计链接中加入含中文的活动名称、把跳转地址作为参数传递。 写程序时优先使用语言自带的URL构造工具或URLSearchParams,编码只在值进入URL的位置做一次。想把编码后的地址做成二维码,可以配合二维码生成器。
常见问题
应该编码整个URL还是只编码一部分?
通常只编码参数的值,比如 q= 后面的搜索词。用参数值模式处理整个网址,冒号和斜杠也会被转义,链接就打不开了。只有想整理一个已经写好的地址中的中文和空格时,才选"整个URL"。
解码时提示出错怎么办?
多半是%后面不足两位十六进制数、内容被截断,或原文不是UTF-8编码(如GBK)。如果想表示百分号本身,应写成 %25。
空格该用+还是%20?
拿不准就用%20。路径里只有%20是正确的,查询串里两者都常见。真正的加号必须写成%2B。
字母和数字会被编码吗?
不会。字母、数字和 - _ . ~ 永远不变。在参数值模式下,! ' ( ) * 默认也保留,打开严格模式才会转义。
输入的内容会上传到服务器吗?
不会,所有转换都在你的浏览器里完成。但要记住,把敏感信息放进URL本身就可能在日志等地方被留存。
相关工具
- Base64编码解码 - 用文本携带字节数据的另一种方式
- 二维码生成器 - 把编码后的网址做成二维码
- 正则表达式测试器 - 校验或提取字符串
- JSON格式化 - 整理放入参数的JSON