redirect_uri 与查询参数中的 encodeURI 和 encodeURIComponent
通过真实场景解释何时应编码完整 URL,何时应只编码单个参数或嵌套值。
很多 URL 编码问题并不是因为选错了函数,而是因为在错误的边界上使用了正确的函数。开发者看到重定向失败后,往往直接在 encodeURI 和 encodeURIComponent 之间二选一,结果只修好了一个测试场景,却在另一个场景里引入了新的问题。
真正应该先回答的问题不是“哪个函数更好”,而是“我现在编码的到底是什么”。它是浏览器最终要读取的完整 URL,还是要放进另一个 URL 里的单个值?这个边界一旦明确,编码方式的选择就会清晰很多。
把完整 URL 和嵌套值视为两种不同的边界
如果你眼前的字符串本身就是浏览器最终要访问的 URL,那么 encodeURI 风格通常更合理,因为它会保留 /、?、&、= 这些顶层分隔符的可读性。
但如果这个字符串即将作为一个值被放进另一个 URL 里,情况就变了。嵌套的 redirect_uri 通常应该先作为单个 component 编码,否则它自己的 ?、&、= 很可能在外层 query string 中提前泄漏出来。
Note线上最常见的错误,就是把嵌套 URL 当成已经处于顶层的最终 URL 来处理。
当你不确定边界时,用 URL Encoder 对比两种结果,通常比盲目试错更可靠。
本节相关工具
必须整体保留的值,应按单个 component 编码
如果一个 query value 里包含空格、&、=,甚至另一个 URL,那么在拼到外层 URL 之前,通常应该先把它作为单个 component 编码。否则外层 parser 会过早拆分,把值的一部分误当成新的参数。
Wrong:
/login?redirect_uri=https://app.example.com/callback?from=pricing&utm=ads
Safer:
/login?redirect_uri=https%3A%2F%2Fapp.example.com%2Fcallback%3Ffrom%3Dpricing%26utm%3Dads
第二种写法虽然不够直观,但更安全,因为嵌套目标会被保留为一个完整单元。在这种边界下,encodeURIComponent 风格通常更合适。
在再次编码之前,先确认是否已经过度编码
当输入里已经出现 %3A、%2F 或大量 %25 这样的序列时,再做一次编码往往不是修复,而是在掩盖真正的问题。许多重定向 bug 的根源,就是同一个值在不同层被重复编码。
更稳妥的流程是:
- 先观察当前输入原样
- 判断它是完整 URL 还是单个 component
- 只在那个边界上编码一次
- 调试时如有需要,再解码一次查看内部结构
如果你无法清楚说明编码责任属于哪个层,那就说明现在还不应该继续补一层编码。
本节相关工具
URL Encoder
Encode a full URL or a single nested component with the right boundary, then copy a clean result for redirects, query parameters, and callback links.
URL Decoder
Decode percent-encoded URL strings back to human-readable plain text.
URL Query Parameter Inspector
Inspect a full URL, decode query values, group duplicate keys, and flag suspicious tracking parameters directly in your browser.