En realidad, todas las respuestas anteriores contienen al menos algunas imprecisiones, que para muchos valores comunes de usuario proporcionada texto en los campos de texto no comunicarse correctamente con el servidor
stringByAddingPercentEscapesUsingEncoding:
ciento escapa todos los caracteres que no son URL válida caracteres. Este método debería aplicarse una vez a la URL completa.
Una respuesta anterior afirma que stringByAddingPercentEscapesUsingEncoding:
funciona como las clases de construcción de URL en muchos lenguajes de scripting, donde no debe aplicarlo a la cadena de URL completa, pero no es así. Cualquiera puede verificar esto fácilmente verificando su salida para &
s sin protección y ?
s. Por lo tanto, está bien aplicarlo a toda la cadena, pero no es suficiente para aplicarlo a su contenido de URL 'dinámico'.
La respuesta anterior es correcta en cuanto a que debe trabajar un poco más con los nombres y valores que entran en su cadena de consulta CGI. Como CGI está especificado por RFC3875, esto se conoce como porcentaje de escape de RFC3875.Se asegura de que sus nombres y valores no contienen caracteres que no son caracteres de URL válidos, pero que son importantes en otras partes de la URL (;
, ?
, :
, @
, &
, =
, $
, +
, {
, }
, <
, >
y ,
)
Sin embargo, es muy importante terminar también haciendo escapes simples de porcentaje de URL en la cadena completa para asegurarse de que todos los caracteres de la cadena sean caracteres URL válidos. Si bien no lo hace en su ejemplo, en general podría haber caracteres en una parte "estática" de la cadena que no son caracteres de URL válidos, por lo que también debe escapar de ellos.
Desafortunadamente, NSString
no nos da el poder de escapar de los caracteres significativos RFC3875, así que tenemos que sumergirnos en CFString
para hacerlo. Obviamente usando CFString
es un dolor por lo que generalmente agrego un Category
en NSString
así:
@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
Con esta Category
en su lugar, el problema original podría ser resuelto correctamente con los siguientes:
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];
Esto se un poco variable pesado solo sea más claro. También tenga en cuenta que la lista de variables proporcionada a stringWithFormat:
no debe ser nil
terminada. La cadena de formato describe la cantidad precisa de variables que deberían seguirla. Además, técnicamente las cadenas para los nombres de cadena de consulta (nombre, etiquetas, entrada, ...) se deben ejecutar a través de stringByAddingPercentEscapesUsingEncoding:
como una cuestión de rutina, pero en este pequeño ejemplo podemos ver fácilmente que no contienen caracteres de URL no válidos.
Para ver por qué las soluciones anteriores son incorrectas, imagine que el texto de entrada del usuario en dreamEntry.text
contiene un &
, que no es poco probable. Con las soluciones anteriores, todo el texto que sigue a ese carácter se perderá en el momento en que el servidor recibió ese texto, ya que el símbolo comercial sin escinde sería interpretado por el servidor como el final de la porción del valor de ese par de cadenas de consulta.
jeje punto tomado. ¡Gracias! – bcsantos