NSURL URLWithString:relativeToURL: 正在裁剪相对 url

Posted

技术标签:

【中文标题】NSURL URLWithString:relativeToURL: 正在裁剪相对 url【英文标题】:NSURL URLWithString:relativeToURL: is clipping relative url 【发布时间】:2013-05-11 01:06:33 【问题描述】:

我正在尝试实现一个使用 RestKit 的 ios 应用程序。到目前为止,在我看到的所有示例中,都使用以下代码来创建 URL:

NSURL *baseURL = [NSURL URLWithString:@"https://api.service.com/v1"];
NSURL *relativeURL = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL];

但随后[relativeURL absoluteString] 将返回https://api.service.com/files/search

所以我尝试了几个例子:

NSURL *baseURL1 = [NSURL URLWithString:@"https://api.service.com/v1/"];
NSURL *baseURL2 = [NSURL URLWithString:@"https://api.service.com/v1"];
NSURL *baseURL3 = [NSURL URLWithString:@"/v1" relativeToURL:[NSURL URLWithString:@"https://api.service.com"]];

NSURL *relativeURL1 = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL1];
NSURL *relativeURL2 = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL2];
NSURL *relativeURL3 = [NSURL URLWithString:@"/files/search" relativeToURL:baseURL3];
NSURL *relativeURL4 = [NSURL URLWithString:@"files/search" relativeToURL:baseURL1];
NSURL *relativeURL5 = [NSURL URLWithString:@"files/search" relativeToURL:baseURL2];
NSURL *relativeURL6 = [NSURL URLWithString:@"files/search" relativeToURL:baseURL3];

NSLog(@"1: %@", [relativeURL1 absoluteString]);
NSLog(@"2: %@", [relativeURL2 absoluteString]);
NSLog(@"3: %@", [relativeURL3 absoluteString]);
NSLog(@"4: %@", [relativeURL4 absoluteString]);
NSLog(@"5: %@", [relativeURL5 absoluteString]);
NSLog(@"6: %@", [relativeURL6 absoluteString]);

这是输出:

1: https://api.service.com/files/search
2: https://api.service.com/files/search
3: https://api.service.com/files/search
4: https://api.service.com/v1/files/search
5: https://api.service.com/files/search
6: https://api.service.com/files/search

所以返回我想要的唯一示例是#4。谁能解释一下为什么?

【问题讨论】:

【参考方案1】:

另一个例子:

//it's right
NSURL *url = [NSURL URLWithString:@"getValidNumber" relativeToURL:[NSURL URLWithString:@"http://dns.test.com:22009/service/"]]; 

//error
NSURL *url = [NSURL URLWithString:@"getValidNumber" relativeToURL:[NSURL URLWithString:@"dns.test.com:22009/service/"]]; 

//error
NSURL *url = [NSURL URLWithString:@"/getValidNumber" relativeToURL:[NSURL URLWithString:@"http://dns.test.com:22009/service"]];

` 'http://' 是使用此方法所必需的。

【讨论】:

【参考方案2】:

我阅读了[RFC1808],它定义了解析相对 URL 的规范算法

2 个问题:

    相对 url 可能不以 / 开头,或者它被认为是绝对的:

     Step 4: If the embedded URL path is preceded by a slash "/", the
        path is not relative and we skip to Step 7."
    

    当基本 url 以非斜杠结尾时。从最后一个斜线开始的所有内容都被跳过

     Step 6: The last segment of the base URL's path (anything
        following the rightmost slash "/", or the entire path if no
        slash is present) is removed and the embedded URL's path is
        appended in its place.  The following operations are
        then applied, in order, to the new path:"
    

这样就可以解释了。 baseURL 需要以 / 结尾,并且相对 url 不应以 / 开头

【讨论】:

@downvoter 请解释为什么......是因为领先的 /?我明白了,因此对其进行了编辑,并对麦克投了赞成票。但请在您投反对票时发表评论 再次:最新的投票者请您发表评论,以便我可以在需要时修复它 baseURL 需要以 / 结尾,而相对 url 不应该以 / 开头,这是绝对正确的:)。我在基本 url 和路径上遇到一些问题。你能添加[RFC1808]的链接吗【参考方案3】:

这里有两个问题:

首先,字符串/files/search 是一个绝对 路径,因为它以斜杠开头。针对任何现有 URL 解析它将忽略现有路径。

其次,https://api.service.com/v1 没有尾部斜杠来表示它是一个目录。任何针对它解析的字符串将始终忽略 v1 部分。

总之,您需要相对路径(files/search)和目录基 URL(https://api.service.com/v1/)的组合。

【讨论】:

以上是关于NSURL URLWithString:relativeToURL: 正在裁剪相对 url的主要内容,如果未能解决你的问题,请参考以下文章

来自字符串的 NSURL 不起作用

IOS NSURL基本操作-备

Swift 中的 NSURL 数组错误?

NSString 到 NSurl

如何获取文档目录的“NSURL”?

如何在 NSURL 中使用特殊字符?