Swift中如何避免URL对[]字符执行百分编码?
在Swift中保留URL里的方括号([])不被百分编码的解决办法
嘿,这个问题我之前对接特殊API的时候也碰到过!Swift的URL初始化器默认会按照RFC标准对很多特殊字符做百分编码,方括号[]刚好在这个列表里,但既然你的API文档明确要求保留原始的[],咱们有两种靠谱的解决办法:
方法1:用URLComponents精细控制编码规则
URLComponents是Swift里构建URL更灵活的方式,它允许我们自定义哪些字符不需要被编码。具体步骤是创建一个排除了[]的字符集,然后用它来处理参数或者路径:
func attemptPubgIDLookup(playerName: String, completion: @escaping (String) -> Void) { let region = "pc-na" // 初始化基础URL组件 guard var components = URLComponents(string: "https://api.playbattleground.com") else { completion("URL基础路径无效") return } // 设置包含方括号的API路径(比如你的接口路径是/players[filter]) components.path = "/players[filter]" // 自定义允许的字符集:从默认的URL查询允许字符集中移除[] var allowedCharacters = CharacterSet.urlQueryAllowed allowedCharacters.remove(charactersIn: "[]") // 构造查询参数,用自定义字符集编码playerName let queryItems = [ URLQueryItem(name: "region", value: region), URLQueryItem(name: "playerName", value: playerName.addingPercentEncoding(withAllowedCharacters: allowedCharacters)) ] components.queryItems = queryItems // 最终得到保留[]的URL guard let finalUrl = components.url else { completion("URL构造失败") return } print(finalUrl.absoluteString) // 这里继续你的API请求逻辑,比如用URLSession发起请求 }
方法2:先拼接原始字符串,再手动还原方括号
如果你更习惯直接拼接URL字符串,可以先拼出包含[]的原始串,初始化URL后再把自动编码的%5B和%5D替换回[]。不过这种方法要注意只替换目标字符,避免破坏其他合法编码:
func attemptPubgIDLookup(playerName: String, completion: @escaping (String) -> Void) { let region = "pc-na" // 先定义包含[]的原始URL模板 let rawUrlTemplate = "https://api.playbattleground.com/players[filter]?region=\(region)&playerName=%@" // 先对playerName做编码,但排除[] let allowedCharacters = CharacterSet.urlQueryAllowed.subtracting(CharacterSet(charactersIn: "[]")) guard let encodedPlayerName = playerName.addingPercentEncoding(withAllowedCharacters: allowedCharacters) else { completion("玩家名称编码失败") return } // 拼接完整的原始字符串 let rawUrlString = String(format: rawUrlTemplate, encodedPlayerName) // 初始化URL后,把编码后的方括号还原 guard let encodedUrl = URL(string: rawUrlString), let decodedUrlString = encodedUrl.absoluteString .replacingOccurrences(of: "%5B", with: "[") .replacingOccurrences(of: "%5D", with: "]"), let finalUrl = URL(string: decodedUrlString) else { completion("URL构造失败") return } print(finalUrl.absoluteString) // 继续你的API请求逻辑 }
注意事项
- 只有当API文档明确要求保留未编码的
[]时才使用这些方法,因为按照HTTP标准,方括号属于需要编码的保留字符,大部分正规API都会接受编码后的%5B和%5D。 - 如果只有URL路径里包含
[],查询参数不需要,那可以只处理路径部分,查询参数用默认编码即可,这样更安全。
内容的提问来源于stack exchange,提问作者Alex Ritter
相关产品推荐
相关产品推荐

