
在使用 URLSearchParams 设置含 $ 等特殊字符的参数名时,浏览器默认将其 URL 编码为 %24;本文介绍如何安全、可靠地在最终 URL 中还原原始 $ 符号,同时保持参数值正常编码。
在使用 `urlsearchparams` 设置含 `$` 等特殊字符的参数名时,浏览器默认将其 url 编码为 `%24`;本文介绍如何安全、可靠地在最终 url 中还原原始 `$` 符号,同时保持参数值正常编码。
在构建动态 URL 时,若需将 $ 用作参数名前缀(例如 $filter、$top 等常见于 OData 或自定义 API 协议),直接使用 URLSearchParams.set() 会导致 $ 被自动转义为 %24 —— 这是符合 RFC 3986 规范的标准行为,因为 $ 在 URL 中属于“未保留字符”(unreserved characters 仅包含 A–Z a–z 0–9 - _ . ~),其编码是 URLSearchParams 内置逻辑强制执行的,无法通过 encodeURI() 或 encodeURIComponent() 在设置阶段绕过。
关键在于:不要试图在参数设置或序列化前“干预编码”,而应在最终生成完整 URL 字符串后,精准替换已编码的 $ 形式。这是因为:
- params.set('$param1', '60') 中的 $ 会被立即编码;
- params.toString() 返回的是完全编码后的查询字符串(如 %24param1=60);
- encodeURI(params.toString()) 会二次编码,导致错误(如 %2524param1=60);
- 而 myUrl.toString() 返回的是完整 URL,其中仅 $ 的编码需要修正,其余字符(如空格、/、中文等)必须保持原编码状态以确保语义正确。
✅ 正确做法如下:
const myUrl = new URL("https://api.example.com/data");
// 直接设置含 $ 的参数名(无需预编码)
myUrl.searchParams.set('$filter', "name eq 'John'");
myUrl.searchParams.set('$top', '10');
// 生成最终 URL,并仅将 %24 替换为 $
const finalUrl = myUrl.toString().replace(/%24/g, '$');
console.log(finalUrl);
// 输出:https://api.example.com/data?$filter=name%20eq%20'John'&$top=10⚠️ 注意事项:
- 仅替换 %24,不可全局替换 $:原始 URL 路径或哈希中若存在合法 $(极少见),不应被误改;
- 区分参数名与参数值:本方案只修复参数名中的 $;参数值中的 $(如 $filter=price gt $100)若需保留,应同样按需替换,但需更谨慎(建议对值单独编码后再注入);
- 服务端兼容性是前提:此技巧依赖服务端能正确解析未编码的 $。绝大多数现代 Web 框架(Express、ASP.NET Core、Spring Boot)默认接受 $ 作为合法查询参数名字符,无需额外配置;
- 不推荐覆盖 URLSearchParams 原型:强行修改内置类行为会破坏可维护性与跨环境一致性,应避免。
? 总结:URLSearchParams 的编码行为不可禁用,但可通过 toString().replace(/%24/g, '$') 在最终环节做最小化、安全的字符串修正。该方案简洁、可靠、无副作用,是处理 $ 类特殊参数名的事实标准实践。










