iOS: проблема с амперсандом в строке URL - PullRequest
23 голосов
/ 01 апреля 2009

Как мы передаем строку Mr.X & Mr.Y в URL.

Я пробовал это, но этот делает все символы, кроме амперсанда.

[urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]

Ответы [ 6 ]

36 голосов
/ 28 июля 2009

Или даже короче:

@implementation NSString (Escaping)
- (NSString*)stringWithPercentEscape {            
    return [(NSString *) CFURLCreateStringByAddingPercentEscapes(
        NULL, 
        (CFStringRef)[[self mutableCopy] autorelease], 
        NULL, 
        CFSTR("=,!$&'()*+;@?\n\"<>#\t :/"),
        kCFStringEncodingUTF8) autorelease];
}
@end

И здесь снова в качестве вспомогательного параметра встроенной функции ARC:

#if __has_feature(objc_arc)
static inline NSString *hxURLEscape(NSString *v) {
    static CFStringRef _hxURLEscapeChars = CFSTR("=,!$&'()*+;@?\r\n\"<>#\t :/");
    return ((__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(
        NULL, 
        (__bridge CFStringRef)[v mutableCopy], 
        NULL, 
        _hxURLEscapeChars, 
        kCFStringEncodingUTF8));
}
#endif
32 голосов
/ 01 апреля 2009

-stringByAddingPercentEscapesUsingEncoding: не выполняет полное escape-кодирование. Вы должны вручную добавить кодировки, используя -replaceOccurrencesOfString:withString:

Вот полный список (зеркально отображающий список Gamecat), как первоначально предлагалось на https://devforums.apple.com/message/15674#15674. Как отмечает Ник, это дорого, поэтому не просто включайте полный список без учета ваших реальных требований к побегу.

NSMutableString *escaped = [actionString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];   
[escaped replaceOccurrencesOfString:@"$" withString:@"%24" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"&" withString:@"%26" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"+" withString:@"%2B" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"," withString:@"%2C" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"/" withString:@"%2F" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@":" withString:@"%3A" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@";" withString:@"%3B" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"=" withString:@"%3D" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"?" withString:@"%3F" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"@" withString:@"%40" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@" " withString:@"%20" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"\t" withString:@"%09" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"#" withString:@"%23" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"<" withString:@"%3C" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@">" withString:@"%3E" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"\"" withString:@"%22" options:NSCaseInsensitiveSearch range:wholeString];
[escaped replaceOccurrencesOfString:@"\n" withString:@"%0A" options:NSCaseInsensitiveSearch range:wholeString];

Этот код, безусловно, составляет хэш вашего URL.

4 голосов
/ 01 апреля 2009

Используйте% 26 в качестве escape-адреса.

Другие побеги:

$  %24
&  %26
+  %2B
,  %2C
/  %2F
:  %3A
;  %3B
=  %3D
?  %3F
@  %40
0 голосов
/ 03 августа 2018

CFURLCreateStringByAddingPercentEscapes устарело (начиная с iOS9), так как насчет простого изменения URLQueryAllowedCharacterSet для удаления зарезервированных символов, что позволяет эффективно кодировать их в процентах относительно ?

- (NSString *)URLQueryValueEncodedString:(NSString *)string {
    static NSMutableCharacterSet *_allowedCharacterSet = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSString *reservedCharacters = @"=,!$&'()*+;@?\r\n\"<>#\t :/[]%";
        _allowedCharacterSet = [NSCharacterSet URLQueryAllowedCharacterSet].mutableCopy;
        [_allowedCharacterSet removeCharactersInString:reservedCharacters];
    });

    return [string stringByAddingPercentEncodingWithAllowedCharacters:_allowedCharacterSet];
}
0 голосов
/ 13 мая 2013

stringByAddingPercentEscapesUsingEncoding также не работает должным образом с +.

Вот более простое решение:

[[[urlString stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding] stringByReplacingOccurrencesOfString:@"&" withString:@"%26"] stringByReplacingOccurrencesOfString:@"+" withString:@"%2b"];
0 голосов
/ 01 апреля 2009

В URL-адресе амперсанд является защищенным ключевым словом, означающим включение переменной строки запроса. Вы не можете поместить это как часть самой ценности. Вам нужно изменить это на что-то другое.

Вот ссылка на тот же вопрос, заданный в StackOverflow: Амперсанд ASP.Net URLEncode для использования в строке запроса

...