gpt4 book ai didi

objective-c - Objective-C 和 Swift 中 URL 编码方法的不一致

转载 作者:可可西里 更新时间:2023-11-01 00:40:31 25 4
gpt4 key购买 nike

我有以下 Objective-C 代码:

[@"http://www.google.com" stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]];
// http%3A//www.google.com

然而,在 Swift 中:

"http://www.google.com".addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)
// http://www.google.com

我可以将这种差异归因于什么?

..为了获得额外的奖励,我能否在传递这样的完整 url 时依靠此代码对 url 路径保留字符进行编码?

最佳答案

问题实际上在于 NSString 方法 stringByAddingPercentEncodingWithAllowedCharactersString 方法 addingPercentEncoding(withAllowedCharacters:) 之间的区别.而且这种行为在不同版本之间一直在变化。 (看起来 iOS 11 的最新测试版现在恢复了我们过去看到的这种行为。)

我认为问题的根源在于路径的百分比编码方式的细节。 RFC 3986 的第 3.3 节表示路径中允许使用冒号,但相对路径的第一段除外。

NSString 方法捕获了这个概念,例如想象一个路径,其第一个目录是 foo:(带冒号)和 bar: 的子目录(也带冒号):

NSString *string = @"foo:/bar:";
NSCharacterSet *cs = [NSCharacterSet URLPathAllowedCharacterSet];
NSLog(@"%@", [string stringByAddingPercentEncodingWithAllowedCharacters:cs]);

结果是:

foo%3A/bar:

页面第一段中的 : 是百分比编码,但后续段中的 : 不是。这捕获了如何根据 RFC 3986 处理相对路径中的冒号的逻辑。 .

但是,String 方法 addingPercentEncoding(withAllowedCharacters:) 不会这样做:

let string = "foo:/bar:"
os_log("%@", string.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed)!)

产量:

foo:/bar:

显然,String 方法不会尝试那种位置敏感的逻辑。这个实现更符合方法的名称(它只考虑哪些字符是“允许的”,没有试图猜测的特殊逻辑,基于允许的字符出现的位置,它是否真的被允许。)


我知道您对问题中提供的代码感到厌烦,但我们应该注意,这种在相对路径中转义冒号的行为虽然对解释您的经历很有趣,但与您眼前的问题并不真正相关。您提供的代码根本不正确。它试图对 URL 进行百分比编码,就好像它只是一条路径一样。但是,这不是一条路;它是一个 URL,它有自己的规则。

对 URL 百分比编码的更深入理解是承认 URL 的不同组成部分允许不同的字符集,即它们需要不同的百分比编码。这就是为什么 NSCharacterSet 有这么多不同的 URL 相关字符集。

您确实应该对各个组件进行百分比编码,对每个组件使用该类型组件允许的字符集进行百分比编码。只有当单独的组件被百分比编码时,它们才应该连接在一起形成整个 URL。

或者,NSURLComponents正是为此目的而设计的,让您摆脱自己对各个组件进行百分比编码的杂草。例如:

var components = URLComponents(string: "http://httpbin.org/post")!
let foo = URLQueryItem(name: "foo", value: "bar & baz")
let qux = URLQueryItem(name: "qux", value: "42")
components.queryItems = [foo, qux]

let url = components.url!

这会产生以下内容,& 和两个空格在 foo 值内正确转义,但它正确地离开了 &fooqux 之间:

http://httpbin.org/post?foo=bar%20%26%20baz&qux=42

但值得注意的是,NSURLComponents 有一个小但相当基本的缺陷:具体来说,如果您有查询值,NSURLQueryItem , 可能有 + 字符,大多数网络服务需要转义百分比,但 NSURLComponents 不会。如果您的 URL 具有查询组件并且如果这些查询值可能包含 + 字符,我建议不要使用 NSURLComponents,而是建议您自己对 URL 的各个组件进行百分比编码。

关于objective-c - Objective-C 和 Swift 中 URL 编码方法的不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44381108/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com