NSURL 用冒号打破端口字符串

NSURL breaking port string with colon

我正在尝试为我的网络代码添加一个基础 url,问题是这个 URL 在传递给 URLWithString:relativeToURL: 方法时被破坏了。这个 URL 有我正在使用的端口,但是,调用描述后, URL 是错误的,不包括我当前的端口号。我认为这是 percent escapers 的问题,但我已经尝试了一些方法来解决这个问题但没有成功。

这是我的代码:

// absolute string returns a url a with broken path
[[NSURL URLWithString:@"api/whatever" relativeToURL:[NSURL URLWithString:@"193.178.0.99:9000"]] absoluteString]
// printed absolute path 193.173.0.99:///api/whatever

其他尝试过的方法:

NSString *baseURLString = (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,(CFStringRef)@"193.178.0.99:9000",NULL,(CFStringRef)@":",kCFStringEncodingUTF8);
[[NSURL URLWithString:@"api/whatever" relativeToURL:[NSURL URLWithString:baseURLString]]
// Printed path : 193.173.0.99%3A8000/api/whatever, this path is still not working, although i have the percent escape set.

NSString *baseURLString = [@"193.173.0.99:8000" stringByAddingPercentEscapesUsingEncoding : NSUTF8StringEncoding];
// ... The same final code from above.
// Printed -> the very same first result.

编辑:来自 URLWithString:relativeToURL: 上方的评论:"These methods expect their string arguments to contain any percent escape codes that are necessary."

有人能解决这个问题吗?

谢谢。

其实解决方案很简单...只需添加方案即可。

像这样:

NSURL *baseURL = [NSURL URLWithString:@"http://193.178.0.99:9000"];
NSString *absoluteString = [[NSURL URLWithString:@"api/whatever" relativeToURL:baseURL] absoluteString];

// Prints => http://193.178.0.99:9000/api/whatever

这种行为实际上是可以理解的(从 RFC 的角度来看):relativeToURL 部分应该是成熟的 URL 根, 包括 URL 方案.

因此在您的示例中,由于您没有提供 http:// 方案或类似方案,因此 193.178.0.99 被视为方案 — 就像 httphttpsftptelmailto — 并且 9000 端口被认为是 URL 的 host 部分(但是因为根据 RFC,9000 可能不是有效的主机,这可能是你顺便收到警告的原因)

在某种程度上,193.178.0.99:9000 以类似的方式解释为 phone-数字 URL tel:1-541-754-3010 或邮件 URL mailto:john.doe@nowhere.com 将; : 将 URL 方案与主机分开,而不是将主机与端口分开。


要解决这个问题,只需在 relativeToURL 参数中包含 URL 方案(如 httphttps 或您打算使用的任何协议):

[[NSURL URLWithString:@"api/whatever"
        relativeToURL:[NSURL URLWithString:@"http://193.178.0.99:9000"]]
 absoluteString];                         // ^^^^^~~ this is the important part

注意:作为构建 URL 的替代解决方案,您可以使用 iOS7 的 NSURLComponents class 来操纵 NSURL 分开,这是另一种分解和构建 URLs

的方法