NSURL URLWithString:relativeToURL:剪切相对URL

时间:2013-05-16 08:21:24

标签: ios url nsurl

我正在尝试使用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。任何人都可以解释原因吗?

3 个答案:

答案 0 :(得分:49)

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

2个问题:

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

    Step 4: If the embedded URL path is preceded by a slash "/", the
       path is not relative and we skip to Step 7."
    
  2. 当基本网址以非斜杠结尾时。从最后一个斜杠开始的所有内容都被跳过

    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:"
    
  3. 所以解释它。 baseURL需要以/结尾,并且相对url不应以/

    开头

答案 1 :(得分:9)

这里有两个问题:

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

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

总而言之,您需要相对路径的组合 - files/search - 和目录基础网址 - https://api.service.com/v1/

答案 2 :(得分:0)

另一个例子:

//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"]];

`