Swift中如何处理URL特殊字符的选择性编码需求
问题原因
你使用的.urlQueryAllowed字符集是为单个查询参数的键/值设计的,会自动把#、?这类URL结构分隔符纳入需要编码的范围,因此直接对完整URL使用这个字符集编码时就会出现结构字符被误编码的问题。
解决方案
这里提供两种经过验证的实现方式,都不需要手动替换字符:
方案1:自定义保留字符集(轻量快速)
按照RFC 3986 URL规范,把所有URL结构允许的ASCII字符都加入允许列表,编码时只会处理非ASCII字符(比如西里尔字母),完全保留结构特殊字符:
// 1. 完全解码原始编码URL let originalEncodedUrl = "https://hello.com/%23/search%3Ftext=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82" guard let decodedUrlStr = originalEncodedUrl.removingPercentEncoding else { // 自定义解码失败的处理逻辑 fatalError("URL解码失败") } // 2. 定义RFC3986规范下所有不需要编码的ASCII字符集合 let rfc3986AllowedSet = CharacterSet(charactersIn: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=") // 3. 重新编码,仅非ASCII字符会被转码 guard let finalEncodedUrlStr = decodedUrlStr.addingPercentEncoding(withAllowedCharacters: rfc3986AllowedSet) else { fatalError("URL编码失败") } // 输出结果:https://hello.com/#/search?text=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82 print(finalEncodedUrlStr)
方案2:URLComponents结构化处理(更严谨)
如果你的URL结构复杂,包含多段路径、多个查询参数,用系统原生的URL组件解析工具处理更稳妥,不需要手动维护字符集,系统会自动按URL各部分的规范处理编码:
let originalEncodedUrl = "https://hello.com/%23/search%3Ftext=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82" guard let decodedUrlStr = originalEncodedUrl.removingPercentEncoding, // 拆分解码后的URL为标准结构组件 var components = URLComponents(string: decodedUrlStr) else { fatalError("URL解析失败") } // 系统自动按规范编码非ASCII字符,保留所有结构分隔符 guard let finalUrl = components.url else { fatalError("URL生成失败") } // 输出结果:https://hello.com/#/search?text=%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82 print(finalUrl.absoluteString)
内容的提问来源于stack exchange,提问作者neo
相关产品推荐
相关产品推荐

