NSURL URLWithString: relativeToURL: découpe l'url relative

J'essaie d'implémenter une application iOS, qui utilise RestKit. Dans tous les exemples que j'ai vus jusqu'à présent, le code suivant est utilisé pour créer les URL:

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

Mais alors {[3] } retournera https://api.service.com/files/search.

J'ai donc essayé quelques exemples:

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

Et c'est la sortie:

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

Donc, le seul exemple renvoyant ce que je veux est #4. Quelqu'un peut-il expliquer pourquoi?

22
demandé sur Mike Abdullah 2013-05-16 12:21:24

3 réponses

J'ai lu [RFC1808] qui définit l'algorithme normatif pour résoudre les URL relatives

2 Questions:

  1. L'url relative peut ne pas commencer par un / ou elle est considérée comme absolue:

    Step 4: If the embedded URL path is preceded by a slash "/", the
       path is not relative and we skip to Step 7."
    
  2. Lorsque l'url de base se termine par un non-slash. tout à partir de la dernière barre oblique est ignoré

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

Donc ça explique. le baseURL doit se terminer par un / et l'url relative ne doit pas commencer par un /

46
répondu Daij-Djan 2015-08-31 15:46:03

, Vous avez deux problèmes ici:

Tout d'abord, la chaîne /files/search est un chemin absolu car elle commence par une barre oblique. Le résoudre par rapport à N'importe quelle URL existante ignorera le chemin existant.

Deuxièmement, https://api.service.com/v1 n'a pas de barre oblique finale pour indiquer qu'il s'agit d'un répertoire. Toutes les chaînes résolues par rapport à elle ignoreront toujours la partie v1.

Pour conclure, vous avez besoin de ce combo d'un chemin relatif - files/search - et D'une URL de base de répertoire - https://api.service.com/v1/.

8
répondu Mike Abdullah 2013-05-16 08:50:37

Un autre exemple:

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

` La "http://" est nécessaire pour utiliser cette méthode.

0
répondu tunnySu 2016-01-13 09:13:01