NSURL URLWithString:relativeToURL: is clipping relative url

我的梦境 提交于 2019-11-29 11:31:44

问题


I'm trying to implement an iOS app, which uses RestKit. In all examples I've seen so far the following code is used to create the URLs:

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

But then [relativeURL absoluteString] will return https://api.service.com/files/search.

So I tried a few examples:

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]);

And this is the output:

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

So the only example returning what I want is #4. Can anyone explain why?


回答1:


I read [RFC1808] which defines the normative algorithm for resolving relative URLs

2 issues:

  1. the relative url may not start with a / or it is considered to be absolute:

    Step 4: If the embedded URL path is preceded by a slash "/", the
       path is not relative and we skip to Step 7."
    
  2. when the base url ends with a non-slash. everything from the last slash on is skipped

    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:"
    

so that explains it. the baseURL needs to end in a / and the relative url shouldn't start with a /




回答2:


You have two problems here:

Firstly, the string /files/search is an absolute path since it starts with a slash. Resolving it against any existing URL will ignore the existing path.

Secondly, https://api.service.com/v1 does not have a trailing slash to indicate it's a directory. Any strings resolved against it will always ignore the v1 portion.

To conclude, you need that combo of a relative path — files/search — and directory base URL — https://api.service.com/v1/.




回答3:


Another example:

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

` The 'http://' is necessary to use this method.



来源:https://stackoverflow.com/questions/16582350/nsurl-urlwithstringrelativetourl-is-clipping-relative-url

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!