Agregar datos a una POST NSURLRequest

83

¿Cómo agregas datos a un existente POST NSURLRequest? Necesito agregar un nuevo parámetro userId=2323.

Tim
fuente
3
Describe tu pregunta con algún código.
Tirth

Respuestas:

192

Si no desea utilizar clases de terceros, lo siguiente es cómo configura el cuerpo de la publicación ...

NSURL *aUrl = [NSURL URLWithString:@"http://www.apple.com/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
                                         cachePolicy:NSURLRequestUseProtocolCachePolicy
                                     timeoutInterval:60.0];

[request setHTTPMethod:@"POST"];
NSString *postString = @"company=Locassa&quality=AWESOME!";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *connection= [[NSURLConnection alloc] initWithRequest:request 
                                                             delegate:self];

Simplemente agregue su par clave / valor a la cadena de publicación

Simon Lee
fuente
2
Necesito agregar el nuevo parámetro a una NSURLRequest existente, no crear una nueva solicitud. Creo que primero debe convertirse a NSMutableURLRequest. Lo que no sé es cómo obtener los datos POST existentes.
Tim
1
¿En otras palabras, cómo se obtiene el postString de una solicitud existente?
Tim
1
Puede acceder al - (NSData *) HTTPBody que puede codificar en un NSString, pares clave / valor
Simon Lee
Los datos de publicación existentes están codificados en UTF8 como en su ejemplo. ¿Cómo puedo invertir la codificación? Entonces, ¿crear una nueva cadena con los nuevos parámetros? luego codifique los datos de la nueva publicación
Tim
1
Esto debería funcionar, pero no puedo probarlo en este momento .... NSMutableString * existingPost = [[NSMutableString alloc] initWithData: [req HTTPBody] encoding: NSUTF8StringEncoding]; [existingPost appendFormat: @ "&% @ =% @", @ "nombre", @ "Locassa"];
Simon Lee
16

Todos los cambios en el NSMutableURLRequestdeben realizarse antes de llamar NSURLConnection.

Veo este problema mientras copio y pego el código anterior y lo ejecuto TCPMony veo que la solicitud es en GETlugar de la esperada POST.

NSURL *aUrl = [NSURL URLWithString:@"http://www.apple.com/"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
                                     cachePolicy:NSURLRequestUseProtocolCachePolicy
                                 timeoutInterval:60.0];


[request setHTTPMethod:@"POST"];
NSString *postString = @"company=Locassa&quality=AWESOME!";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *connection= [[NSURLConnection alloc] initWithRequest:request 
                                                         delegate:self];
Kevin
fuente
12

Las publicaciones anteriores sobre la formación de POSTsolicitudes son en gran parte correctas (agregue los parámetros al cuerpo, no la URL). Pero si existe la posibilidad de que los datos de entrada contengan caracteres reservados (por ejemplo, espacios, ampersand, signo más), entonces querrá manejar estos caracteres reservados. Es decir, debe escapar por ciento de la entrada.

//create body of the request

NSString *userid = ...
NSString *encodedUserid = [self percentEscapeString:userid];
NSString *postString    = [NSString stringWithFormat:@"userid=%@", encodedUserid];
NSData   *postBody      = [postString dataUsingEncoding:NSUTF8StringEncoding];

//initialize a request from url

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPBody:postBody];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

//initialize a connection from request, any way you want to, e.g.

NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

Donde el precentEscapeStringmétodo se define como sigue:

- (NSString *)percentEscapeString:(NSString *)string
{
    NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                 (CFStringRef)string,
                                                                                 (CFStringRef)@" ",
                                                                                 (CFStringRef)@":/?@!$&'()*+,;=",
                                                                                 kCFStringEncodingUTF8));
    return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}

Tenga en cuenta que había un NSStringmétodo prometedor , stringByAddingPercentEscapesUsingEncoding(ahora en desuso), que hace algo muy similar, pero resista la tentación de usarlo. Maneja algunos caracteres (por ejemplo, el carácter de espacio), pero no algunos de los otros (por ejemplo, los caracteres +o &).

El equivalente contemporáneo es stringByAddingPercentEncodingWithAllowedCharacters, pero, de nuevo, no se sienta tentado a usarlo URLQueryAllowedCharacterSet, ya que eso también permite +y &pasa sin escapatoria. Esos dos caracteres están permitidos dentro de la "consulta" más amplia, pero si esos caracteres aparecen dentro de un valor dentro de una consulta, deben ser de escape. Técnicamente, puede usar URLQueryAllowedCharacterSetpara construir un conjunto de caracteres mutable y eliminar algunos de los personajes que han incluido allí, o crear su propio conjunto de caracteres desde cero.

Por ejemplo, si nos fijamos en la Alamofire parámetro de codificación , toman URLQueryAllowedCharacterSety luego se eliminan generalDelimitersToEncode(que incluye los caracteres #, [, ], y @, pero debido a un error histórico en algunos viejos servidores web, ni ?tampoco /) y subDelimitersToEncode(es decir !, $, &, ', (, ), *, +, ,, ;, y =). Esta es una implementación correcta (aunque podría debatir la eliminación de ?y /), aunque bastante complicada. Quizás CFURLCreateStringByAddingPercentEscapessea ​​más directo / eficiente.

Robar
fuente
Es cierto stringByAddingPercentEscapesUsingEncoding:, pero stringByAddingPercentEncodingWithAllowedCharacters:funciona bien con todos los personajes. Ejemplo: URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Alejandro Cotilla
@AlejandroDavidCotillaRojas - Puede usar stringByAddingPercentEncodingWithAllowedCharacters, pero no puede usar URLQueryAllowedCharacterSet, ya que eso incluye +y &(esos son caracteres permitidos dentro de la consulta más amplia, pero si esos caracteres aparecen dentro de un valor dentro de una consulta, deben escapar, lo que ese conjunto de caracteres no hará ). Por lo tanto, puede usar URLQueryAllowedCharacterSetpara construir un conjunto de caracteres mutable y eliminar algunos de los personajes que han incluido allí, o crear su propio conjunto de caracteres desde cero. O utilizar CFURLCreateStringByAddingPercentEscapes.
Rob
Gran respuesta, ¡realmente justifica el uso de Alamofire para evitar toda esta profundidad!
Dan Rosenstark
Dado que CFURLCreateStringByAddingPercentEscapesahora está en desuso, debería crear el juego de caracteres apropiado usted mismo. Consulte stackoverflow.com/a/54742187/1271826 .
Rob
8
 NSURL *url= [NSURL URLWithString:@"https://www.paypal.com/cgi-bin/webscr"];
 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:aUrl
                                                        cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                    timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
 NSString *postString = @"userId=2323";
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
Alex Terente
fuente
8

El código de ejemplo anterior fue realmente útil para mí, sin embargo (como se indicó anteriormente), creo que debe usar en NSMutableURLRequestlugar de NSURLRequest. En su forma actual, no pude conseguir que respondiera a la setHTTPMethodllamada. Cambiar el tipo arregló las cosas de inmediato.

David Fulton
fuente
1

Cualquiera que busque una solución rápida

let url = NSURL(string: "http://www.apple.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPBody = "company=Locassa&quality=AWESOME!".dataUsingEncoding(NSUTF8StringEncoding)
mono espacial
fuente