在我们 iOS 客户端的开发中,有一个长期困扰的问题:部分链接打开后,URL 里的参数被序列化了两次。
比如一个原始链接是这样的:
/path?fff[]=jjj ll
结果在 iOS 里打开后,变成了:
/path?fff%255B%255D=jjj%2520ll
注意看:
%5B 又变成了 %255B%20 又变成了 %2520也就是说,参数被二次序列化了。这个问题追了很久,直到最近才找到真正的原因。
在 iOS 标准库 中,[] 被认为是 需要编码的特殊字符。
所以 fff[] 会被序列化成 fff%5B%5D。
[] 不编码,因为很多 Web 框架(例如 PHP)习惯用 ids[] 这种形式传数组。
所以 <a> 标签或 document.createElement("a") 得到的结果里,[] 会原样保留。这就造成了一个差异:
fff[]=jjj ll → fff[]=jjj%20ll(空格被转义,[] 保留)fff[]=jjj ll → fff%5B%5D=jjj%20ll(空格和 [] 都被转义)当一个 URL 在不同环境下被“来回处理”时:
[] 没有被编码[] 必须编码 → %5B%5D%5B%5D 再做一次序列化 → %255B%255D这样,参数就被双重编码了。
在浏览器里:
var a = document.createElement("a");
a.href = "/path?fff[]=jjj ll";
console.log(a.search);
// 输出: ?fff[]=jjj%20ll
在 iOS(Swift)里:
let url = URL(string: "/path?fff[]=jjj ll", relativeTo: baseURL)!
print(url.query ?? "")
// 输出: fff%5B%5D=jjj%20ll
可以清楚看到差异。
在前端解析函数里,强制把 [] 也转义,保证跟 iOS 保持一致:
query: a.search
.replace(/ /g, "%20")
.replace(/\[/g, "%5B")
.replace(/\]/g, "%5D")
这样就不会出现“浏览器保留 [],iOS 又去二次编码”的情况。
使用标准化的 URL + URLSearchParams,而不是自己手写 split:
const u = new URL("/path?fff[]=jjj ll", location.origin);
console.log(u.search); // "?fff%5B%5D=jjj+ll"
console.log(u.searchParams.get("fff[]")); // "jjj ll"
这能确保在所有环境下,参数都被一致地编码。
这个问题折腾了我们很久,直到深入比对 iOS 与浏览器的标准才找到原因:
[] 不强制序列化[] 强制序列化于是跨环境传递 URL 时,很容易出现“二次序列化”的问题。
✅ 最佳实践:
[]URLSearchParams)这样,就能避免再掉进这个双重编码的坑。
在 IntelliJ IDEA 中,提示 “the file size exceeds the configured limit. Code insight features are not available” 表示当前文件的大小超出了 IDEA 的默认限制,因此无法启用代码自动提示、语法高亮等功能。默认文件大小限制为 2.5 MB。 解决方法 方
ProxySQL 是一个高性能、高可用性的 MySQL 代理,旨在为 MySQL 数据库提供负载均衡、读写分离、故障转移、查询缓存等高级功能。它通过在客户端和 MySQL 服务器之间充当中间层,实现对数据库连接和查询的智能管理,从而提升整体系统的性能和可靠性。
一、什么是 settings.xml settings.xml 是 Maven 的配置文件,用于定义用户级别或全局的构建配置。它包含了对 Maven 构建过程影响较大的设置,如: 本地仓库的位置 远程仓库的镜像 代理服务器配置 认证信息(如私有仓库的用户名和