Swift中支持所有特殊字符的URL编码方案咨询
解决Swift中URL完全编码特殊字符的问题
我明白你的困扰——系统提供的那些CharacterSet预设选项(比如.urlQueryAllowed、.urlHostAllowed)确实不会编码所有特殊字符,因为它们是按照URL各部分的合法规则来定义的。比如&在查询参数里是用来分隔键值对的合法字符,所以预设集里会默认允许它,不会转成%26。
要实现包含所有特殊字符的完全编码(比如把&转成%26),你可以试试这几种方案:
方案1:只允许字母数字,编码所有其他字符
如果你希望除了a-z、A-Z、0-9之外的所有字符都被编码,直接用CharacterSet.alphanumerics作为允许集即可:
let myString = "Hello & World: @ Test" let allowedCharacters = CharacterSet.alphanumerics let encodedString = myString.addingPercentEncoding(withAllowedCharacters: allowedCharacters) // 输出结果:Hello%20%26%20World%3A%20%40%20Test
方案2:自定义允许集,移除特定需要编码的字符
如果想保留大部分URL合法字符,只针对&这类特定字符编码,可以先基于预设集修改,移除你想编码的字符:
var allowedSet = CharacterSet.urlQueryAllowed // 移除&,这样它就会被编码 allowedSet.remove(charactersIn: "&") let encodedString = myString.addingPercentEncoding(withAllowedCharacters: allowedSet) // 此时&会被转成%26,其他查询参数允许的字符(比如=、?)会保留
方案3:用底层API精确控制编码字符
如果需要更精细的控制,比如指定哪些特殊字符必须被编码,可以使用Foundation的底层C函数CFURLCreateStringByAddingPercentEscapes:
func fullyEncodeString(_ input: String) -> String? { let inputNSString = input as NSString // 第三个参数是允许不编码的字符(设为nil表示只保留字母数字) // 第四个参数是强制要编码的特殊字符,把你需要的都加进去 let encoded = CFURLCreateStringByAddingPercentEscapes( nil, inputNSString, nil, "!*'();:@&=+$,/?%#[]", CFStringBuiltInEncodings.UTF8.rawValue ) return encoded as String? } // 使用示例 if let result = fullyEncodeString("Test & Example: @") { print(result) // 输出 Test%20%26%20Example%3A%20%40 }
为什么之前的预设集不行?
举个例子:
.urlQueryAllowed允许&,因为它是URL查询参数中分隔多个键值对的标准字符;.urlHostAllowed允许&是因为某些特殊主机名场景下可能会用到;
所有预设集都是为了符合URL规范,保留对应部分的合法字符,而不是做全量编码。
内容的提问来源于stack exchange,提问作者Amit
相关产品推荐
相关产品推荐

