You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:51:06