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?
3 réponses
J'ai lu [RFC1808] qui définit l'algorithme normatif pour résoudre les URL relatives
2 Questions:
-
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."
-
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 /
, 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/
.
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.