На самом деле, все предыдущие ответы содержат по крайней мере некоторые неточности, которые для многих распространенных значений предоставленного пользователем текста в текстовых полях не будут правильно взаимодействовать с сервером.
stringByAddingPercentEscapesUsingEncoding:
процент экранирует все символы, которые не являются допустимыми символами URL. Этот метод следует применить один раз ко всему URL-адресу.
В предыдущем ответе утверждается, что stringByAddingPercentEscapesUsingEncoding:
работает как классы построения URL-адресов на многих языках сценариев, где вы не должны применять его ко всей строке URL-адреса, но это не так. Любой может легко убедиться в этом, проверив вывод на наличие неэкранированных символов &
и ?
. Таким образом, можно применить ко всей строке, но недостаточно применить к вашему «динамическому» содержимому URL.
Предыдущий ответ правильный в том, что вам нужно проделать дополнительную работу с именами и значениями, которые входят в вашу строку запроса CGI. Поскольку CGI указан в RFC3875, это часто называют процентным экранированием RFC3875. Это гарантирует, что ваши имена и значения не содержат символов, которые являются допустимыми символами URL, но имеют значение в других частях URL (;
, ?
, :
, @
, &
, =
, $
, +
, {
, }
, <
, >
и ,
)
Однако очень важно также закончить, выполнив простые переходы процентов URL в полную строку, чтобы убедиться, что все символы в строке являются допустимыми символами URL. Хотя в вашем примере это не так, обычно в «статической» части строки могут быть символы, которые не являются допустимыми символами URL-адреса, поэтому вам также необходимо избегать их.
К сожалению, NSString
не дает нам возможности экранировать значащие символы RFC3875, поэтому для этого нам нужно погрузиться в CFString
. Очевидно, что использовать CFString
неудобно, поэтому я обычно добавляю Category
к NSString
вот так:
@interface NSString (RFC3875)
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding;
@end
@implementation NSString (RFC3875)
- (NSString *)stringByAddingRFC3875PercentEscapesUsingEncoding:(NSStringEncoding)encoding {
CFStringEncoding cfEncoding = CFStringConvertNSStringEncodingToEncoding(encoding);
NSString *rfcEscaped = (NSString *)CFURLCreateStringByAddingPercentEscapes(
NULL,
(CFStringRef)self,
NULL,
(CFStringRef)@";/?:@&=$+{}<>,",
cfEncoding);
return [rfcEscaped autorelease];
}
@end
С этим Category
исходная проблема может быть правильно решена следующим образом:
NSString *urlEscapedBase = [@"http://server.com/file.php" stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *rfcEscapedName = [nameField.text stringByAddingRFC3875PercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *rfcEscapedTags = [tagsField.text stringByAddingRFC3875PercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *rfcEscapedEntry = [dreamEntry.text stringByAddingRFC3875PercentEscapesUsingEncoding:
NSUTF8StringEncoding];
NSString *urlStr = [NSString stringWithFormat:@"%@?name=%@&tags=%@&entry=%@",
urlEscapedBase,
rfcEscapedName,
rfcEscapedTags,
rfcEscapedEntry];
NSURL *url = [NSURL URLWithString:urlStr];
Это немного переменная тяжелая, просто будьте более ясны. Также обратите внимание, что список переменных, предоставленный stringWithFormat:
, не должен быть nil
завершен. Строка формата описывает точное количество переменных, которые должны следовать за ней. Кроме того, технически строки для имен строк запроса (имя, теги, запись,..) должны быть пропущены через stringByAddingPercentEscapesUsingEncoding:
, как само собой разумеющееся, но в этом небольшом примере мы легко видим, что они не содержат недопустимых символов URL.
Чтобы понять, почему предыдущие решения неверны, представьте, что вводимый пользователем текст в dreamEntry.text
содержит &
, что вполне вероятно. В предыдущих решениях весь текст, следующий за этим символом, будет потерян к тому времени, когда сервер получит этот текст, поскольку неэкранированный амперсанд будет интерпретирован сервером как окончание части значения этой пары строк запроса.
person
barrycburton
schedule
10.11.2010