为何URLPathAllowedCharacterSet含冒号却被stringByAddingPercentEncoding编码?
问题:URLPathAllowedCharacterSet包含冒号但仍被编码的原因及解决办法
我在Objective-C中编写了如下测试代码:
NSCharacterSet *pathAllowedCharacterSet = [NSCharacterSet URLPathAllowedCharacterSet]; // 检查冒号是否属于URLPathAllowedCharacterSet if ([pathAllowedCharacterSet characterIsMember:':']) { NSLog(@"Colon is allowed in URL path"); } else { NSLog(@"Colon is not allowed in URL path"); } NSString* test = [@":" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]; NSLog(@"%@", test);
日志输出结果为:
Colon is allowed in URL path %3A
stringByAddingPercentEncodingWithAllowedCharacters的文档说明为:
Returns a new string made from the receiver by replacing all characters not in the specified set with percent-encoded characters.
(中文翻译:返回一个新字符串,该字符串通过将接收者中所有不在指定集合中的字符替换为百分号编码的字符而生成。)
按文档描述,属于指定字符集的字符不应被百分编码,但冒号却被编码了,这是为什么?有没有办法让它不被编码?
解答
原因分析
核心问题在于**URLPathAllowedCharacterSet的字符集定义,和stringByAddingPercentEncodingWithAllowedCharacters:的实际编码逻辑存在额外约束**。
虽然characterIsMember:返回YES,证明冒号确实在该字符集内,但Foundation框架的URL编码逻辑会对路径中的冒号做特殊处理——在URL标准中,冒号容易和协议头的://产生解析歧义,所以框架会主动对路径里的冒号进行编码,哪怕它在允许字符集列表中。
解决办法
如果需要让冒号不被编码,可以通过自定义允许字符集绕过框架的额外处理:
- 先获取
URLPathAllowedCharacterSet的可变副本 - 明确将冒号纳入允许范围(覆盖框架的特殊编码规则)
代码示例:
// 获取URL路径允许字符集的可变副本 NSMutableCharacterSet *customPathSet = [[NSCharacterSet URLPathAllowedCharacterSet] mutableCopy]; // 明确添加冒号到允许集合中 [customPathSet addCharactersInString:@":"]; NSString* test = [@":" stringByAddingPercentEncodingWithAllowedCharacters:customPathSet]; NSLog(@"%@", test); // 输出结果为: :
这样处理后,冒号就不会被百分编码了。
内容的提问来源于stack exchange,提问作者rpatters1
相关产品推荐
相关产品推荐

