工作原理
百分号编码会把每个非保留字符的字节替换成百分号加两位大写十六进制。RFC 3986 把 ASCII 分成三类:非保留字符(A-Z、a-z、0-9、连字符、句点、下划线、波浪号)永不编码;保留字符(: / ? # [ ] @ ! $ 等)具有结构含义,只有作为数据使用时才编码;其余字符一律编码。空格是特例:在几乎所有上下文中 %20 都合法,而用加号表示空格只在 application/x-www-form-urlencoded 请求体中才是正确的。
encodeURI 与 encodeURIComponent 不可互换,混淆二者是经典错误。作为完整 URI 编码时,https://example.com/a b 会保留协议、斜杠和问号,变成 https://example.com/a%20b;作为单个组件编码时,同样的输入会变成 https%3A%2F%2Fexample.com%2Fa%20b,因为此时斜杠和冒号都是数据。如果服务端收到的 URL 里出现 %3A%2F%2F,说明客户端调用了错误的函数。
HTML 实体编码是完全不同的问题。在 HTML 中,&、<、>、引号和撇号都是结构性字符:未转义的 < 会开启一个标签,未转义的 & 会开始一个实体引用,属性内未转义的引号会提前结束属性。转义它们就把标记变成了惰性文本。这正是阻止跨站脚本的机制——包含 script 标签的评论会被当作字符显示而非执行——也是为什么所有模板引擎默认转义,而绕过该默认值的“原始 HTML”辅助函数常常成为漏洞源头。
解码一侧比多数实现更严格。百分号后面若不是两个十六进制数字,就不是可解码序列,静默放过只会掩盖数据损坏,因此本工具会报出位置。HTML 实体会解析完整的命名集合以及十进制和十六进制数字引用,所以 &、& 和 & 都解码为同一个 &。工具还会检验往返一致性,让你确认“先解码再编码”能逐字节还原原始输入。
常见应用场景
- 手工构造查询字符串,对包含空格、& 或中文的搜索词做编码。
- 查看被编码了两次的跟踪链接,弄清真实的目标地址。
- 把用户提供的文本转义后再粘进 HTML 模板或邮件正文。
- 解码 OAuth 的 redirect_uri 参数,找出授权服务器拒绝它的原因。
- 把含有嵌套 URL 的参数编码成回调或 Webhook 配置所需的形式。
- 确认即将写入属性中的值无法突破引号边界。
最后更新: 2026-10-14