分隔符也可能是参数内容
在 https://example.com/search?q=tea&sort=new 中,问号开始查询部分,& 分隔两个参数。但在搜索词 tea & coffee 中,& 是文本本身的内容。
将这段搜索词作为一个组件编码,会得到 tea%20%26%20coffee。组成 q=tea%20%26%20coffee 后,完整短语就保留在 q 的值中。
单个值使用组件模式
处理单个查询参数值或路径片段时,通常应从组件编码开始。可能被当成分隔符的字符会被转换为转义形式。
除非整个网址本身是另一个网址的参数值,否则不要把完整 URL 当成组件编码。把斜杠、冒号和问号全部转义,也会编码外层链接需要的结构。
完整 URL 模式保留已有结构
完整 URL 编码会保留预留的分隔符。它可以处理已有 URI 中的空格或非 ASCII 文本,但无法判断某个 & 原本是数据还是分隔符。
如果未经编码的值已经包含 & 或 #,最后再编码整个链接无法消除歧义。应分别编码各个值后拼接,或使用能处理查询参数的 URL 构造库。
加号不一定代表空格
通用百分号编码使用 %20 表示空格,HTML 表单查询编码也可能使用 +。真正的加号可以表示为 %2B。
ToolRook 的百分号解码不会自动把 + 替换为空格。例如 q=C%2B%2B 中的值解码后是 C++。替换加号前,先确定它是数据还是表单编码中的空格。
每次只解码一层
已有的 %20 再次编码后,百分号会变成 %25,整体得到 %2520。当 URL 嵌套在另一个 URL 里时,这可能是有意设计,但也经常意味着同一个值被误编码了两次。
保留原始文本,每解码一层就检查结果。不要为了让文本看起来正常而连续解码,因为编码后的分隔符还原后可能改变下游程序的解释。编码可以还原,不能保护密码或令牌。
- 不完整的 %2 等转义可能造成解码错误。
- 编码只改变表示方式,不能确认目标网址是否安全。
- 编写软件时尽量使用 URL 或查询参数 API,并检查最终链接。
现在就用工具试一试。
查看全部工具