使用方法
- 输入框默认写着一条完整 URL,只写 ? 之后的 query 串也可以。页面会自动剥掉 ? 之前的部分与 # 之后的片段标识,按 Ctrl+Enter(Mac 上 Cmd+Enter)重新解析。
- 「表格里值的显示长度上限」默认 80,范围 8 到 500,步长 1。它只影响表格里的显示,超出会截断并加省略号,统计与导出仍按完整值计算。
- 解析结果按段顺序列出:键、原值、decodeURIComponent 值、form-urlencoded 值四列并排。两列值不一致时看原值里有没有加号,那通常就是分歧点。
- 重复出现的键会用醒目标记注出,并在统计里给出「去重后键数」与「重复键数」。同一个键出现两次不等于出错,很多接口就靠它传数组。
- 「反向生成的编码口径」决定下面反向框里空格写 %20 还是 +。两者都能被服务端读回,但按哪种口径解析就决定了值里的加号会不会变成空格。
- 反向框默认写着四行 key=value,按 Ctrl+Enter 生成 query 串。同一组键值对在两种口径下会生成两个不同的串:一个带 %20,一个带 +。
- 「复制结果」复制统计与整张键值表;「复制表格」复制键值表的制表符版本;「导出 CSV」把全部键值对存成带 BOM 的文件。
- 输入里没有等号、某段缺等号、百分号编码残缺、显示长度上限越界、反向框某行没有等号,都会给出写明段号或行号的提示。
这个 Query 字符串解析能解决什么问题
把 ? 后面那一串拆成键值对,看起来是个体力活,真正的坑在口径。同一个 q=a+b,用 decodeURIComponent 解出来是 a+b,用 URLSearchParams 取出来是 a b——因为 application/x-www-form-urlencoded 里加号表示空格,而 RFC 3986 的 query 里加号就是加号。本站这一页把两种口径并排列出,就是为了先把分歧摆到台面上。
第一类是调试接口。后端日志里记下的 query 串与前端代码里拼出来的串往往写法不同,把原始串粘进来,四列并排一对比,就能看出究竟是编码口径不一致,还是某处漏了解码。
第二类是排查重复键。?a=1&a=2 在 URLSearchParams 里 get 只取第一个、getAll 才取全部,在 PHP 里后一个覆盖前一个,在有些框架里则解析成数组。本页把重复键标记出来,避免你按「最后一个生效」的直觉去读。
第三类是核对分享链接。运营配的落地页链接常带 utm 参数与中文参数,中文会被编成百分号加十六进制的三字节一组。本页直接解回原文,能确认有没有被二次编码——二次编码的表现是解出来仍是一串百分号。
第四类是估算长度。URL 总长在实际环境里大约到 2000 字符就会出问题,IE 是 2083,现代浏览器与服务器各不相同。本页给出 query 串与完整输入的字符数,超限时会明确提示。
计算原理与变量说明
解析顺序是固定的三步:先按 & 切段 → 再按每段第一个 = 切键值 → 最后各自 decodeURIComponent。顺序不能颠倒。若先解码再切段,编码过的 %26(& 的编码)与 %3D(= 的编码)会被还原成分隔符,把本来属于值的内容切成新的键值对。
第二步只认第一个等号,这一点也很关键:a=1=2 的键是 a、值是 1=2,不是键 a=1 值 2。若整个串里一个等号都没有,本页直接报错而不是把整段当键——那多半是粘错了内容。
两种解码口径的差别只在加号。RFC 3986 的 query 里加号就是普通字符,decodeURIComponent("a+b") 得 a+b;而 form-urlencoded 口径把加号当空格,URLSearchParams 取 q=a+b 得 a b。%20 在任何口径下都是空格,所以 decodeURIComponent("a%20b") 得 a b,两种口径一致。
百分号编码本身按字节工作:一个字节变成百分号加两位十六进制,占 3 个字符。UTF-8 下一个汉字 3 字节,所以「中文」两个字的原始字节是 6,编码后是 %E4%B8%AD%E6%96%87 共 18 个字符,膨胀 9 倍。这是判断一段百分号串大概含几个汉字的快捷办法。
重复键的处理有两种语义,都要知道:?a=1&a=2 上,get("a") 取第一个得 1,getAll("a") 得 [1, 2];构造时 append() 是追加、set() 是删掉重复只留一个。数组语法另有几种写法:PHP 风格 a[]=1&a[]=2、带下标 a[0]=1&a[1]=2、Ruby 与 Node 的 qs 还支持 a[b]=1 这类嵌套。
最后一条是安全边界。query 里的敏感信息(令牌、密码)会同时写进浏览器历史、Referer 请求头与服务器访问日志,任何一环都可能外泄;能用 POST 传的就不要放在 query 里。
完整示例(数值仅作演示)
打开页面时的默认输入是一条完整 URL,query 部分是 q=%E6%9F%B3%E6%B3%89%E5%B7%A5%E5%85%B7&page=2&tag=a+b&tag=c%20d&flag=,共 69 个字符,完整输入 116 个字符。解析出 5 个键值对:q 的值是「柳泉工具」,page 的值是 2,tag 出现两次,flag 是空值。
tag 这一组最值得看:第一次出现是 tag=a+b,decodeURIComponent 给 a+b,form 口径给 a b;第二次出现是 tag=c%20d,两种口径都给 c d。所以同一批结果里,加号那组分歧、%20 那组一致。
反向框默认四行 q=柳泉工具、page=2、tag=a b、tag=c d。按百分号口径生成 q=%E6%9F%B3%E6%B3%89%E5%B7%A5%E5%85%B7&page=2&tag=a%20b&tag=c%20d;改成 form 口径则生成 q=%E6%9F%B3%E6%B3%89%E5%B7%A5%E5%85%B7&page=2&tag=a+b&tag=c+d。两个串长度相同,但只有第一个能被「加号就是加号」的解析口径正确读回。
Query 字符编码对照表
下表列出 query 里最容易出问题的十二个字符,按百分号编码逐行给出。写 query 时这些字符都应当编码,否则会被当成结构符号。
| 字符 | 名称 | 百分号编码 | 不编码会怎样 |
|---|---|---|---|
| 空格 | %20 | 被截断或被当成分隔符 | |
| + | 加号 | %2B | form 口径下被解成空格 |
| & | 与号 | %26 | 被当成下一组键值对的分界 |
| = | 等号 | %3D | 被当成键值分隔,值被切走一段 |
| ? | 问号 | %3F | 被当成 query 起始位置 |
| # | 井号 | %23 | 之后的内容被当成片段标识丢弃 |
| / | 斜杠 | %2F | 被当成路径分隔 |
| : | 冒号 | %3A | 与 scheme 冒号混淆 |
| % | 百分号 | %25 | 被当成转义起始,后面两位被吃掉 |
| , | 逗号 | %2C | 部分网关会做额外切分 |
| 中 | 汉字 | %E4%B8%AD | 非 ASCII 必须编码,一个字 3 字节 |
| @ | at 符 | %40 | 与用户信息段的分隔符混淆 |
结果边界、舍入与适用说明
- 输入为空或全是空白时不会报错,而是把默认示例 URL 填回去再解析。
- 整个串里一个等号都没有时报「没有找到等号」并给出原文,不把整段当成键——那多半是粘错了内容。
- 某一段缺等号时报出段号与该段原文,其余段不再解析,避免把残缺结构当成合法键值对。
- 百分号编码残缺(如 %E4%B 或孤立的 %)时 decodeURIComponent 会抛 URIError,本页捕获后报出段号与原因,不返回半截结果。
- 显示长度上限留空、写成小数或超出 8 到 500 时分别给出对应提示;它只截断表格里的显示,导出与统计始终用完整值。
- 去重后键数与重复键数只统计键名,不比较值。
?a=1&a=1算两个键值对、一个重复键。 - 长度提示里的 2000 字符是实际环境的经验值,IE 的硬限制是 2083,现代浏览器与服务器各不相同;超限只提示,不做截断。
- 本页只做解析与生成,不发起任何请求,也不会替你判断某个参数在目标接口上是否合法。
常见问题
为什么同一个加号有两种解析结果?
因为存在两套规则。RFC 3986 的 query 里加号就是加号,decodeURIComponent("a+b") 得 "a+b";application/x-www-form-urlencoded 里加号表示空格,URLSearchParams 取 q=a+b 得 "a b"。所以同一个 query 串,两种口径在加号处结果不同。
%20 和 + 到底该用哪个?
在 form-urlencoded 语境下两者都表示空格,但 %20 在任何口径下都是空格,而 + 只在 form 口径下是空格。要表达真正的加号,请写成 %2B,否则它在 form 口径下会被解成空格。
解析顺序为什么必须是先切后解?
若先解码再切段,编码过的 %26 与 %3D 会被还原成 & 与 =,把本来属于值的内容切成新的键值对。正确顺序是先按 & 切、再按第一个 = 切、最后各自 decodeURIComponent。
重复键该怎么读?
取决于对端实现。URLSearchParams 的 get 只取第一个,getAll 取全部;PHP 里后一个覆盖前一个;部分框架解析成数组。本页只负责标记重复,读到什么语义要看具体接口。
append 和 set 有什么区别?
append 是追加,同一个键会出现两次;set 会先删掉该键的所有旧值再写入,只留一个。想传数组就用 append,想覆盖就用 set,两者语义不同,混用会得到完全不同的 query 串。
中文参数为什么变成那么长一串?
因为百分号编码按字节工作。UTF-8 下一个汉字 3 字节,每字节变成 3 个字符,所以一个汉字占 9 个字符。中文两个字的原始字节是 6,编码后是 %E4%B8%AD%E6%96%87 共 18 个字符,膨胀 9 倍。
URL 多长会有问题?
实际环境里大约到 2000 字符就会出问题:IE 的硬限制是 2083,现代浏览器与服务器各不相同,超出会被截断或拒收。本页给出 query 串与完整输入的字符数,超 2000 时明确提示。
输入的内容会上传到服务器吗?
不会。query 串、键值对与所有选项只在本页脚本里参与运算,页面没有发起任何网络请求,刷新后输入即回到默认值。