ios - Adjuntar datos a un POST NSURLRequest
objective-c (6)
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)
¿Cómo NSURLRequest
datos a una POST
NSURLRequest
existente? Necesito agregar un nuevo parámetro userId=2323
.
El código de ejemplo anterior fue realmente útil para mí, sin embargo (como se ha insinuado anteriormente), creo que debe utilizar NSMutableURLRequest
lugar de NSURLRequest
. En su forma actual, no pude hacer que respondiera a la llamada setHTTPMethod
. Cambiar el tipo de cosas arregladas directamente.
Las publicaciones anteriores sobre la formación de solicitudes POST
son en gran medida correctas (agregue los parámetros al cuerpo, no a la URL). Pero si hay alguna posibilidad de que los datos de entrada contengan cualquier carácter reservado (por ejemplo, espacios, símbolo comercial, signo más), entonces querrá manejar estos caracteres reservados. A saber, 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 método precentEscapeString
se define de la siguiente manera:
- (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 método prometedor de NSString
, stringByAddingPercentEscapesUsingEncoding
(ahora obsoleto), que hace algo muy similar, pero se resiste a 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, una vez más, no se URLQueryAllowedCharacterSet
tentado a usar URLQueryAllowedCharacterSet
, ya que también permite +
y &
pasar sin guardar. 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 escapar. Técnicamente, puede usar URLQueryAllowedCharacterSet
para crear un juego de caracteres mutable y eliminar algunos de los caracteres que han incluido allí, o crear su propio conjunto de caracteres desde cero.
Por ejemplo, si observa la codificación de parámetros de Alamofire, toma URLQueryAllowedCharacterSet
y luego elimina generalDelimitersToEncode
(que incluye los caracteres #
, [
, ]
y @
, pero debido a un error histórico en algunos servidores web antiguos, ni ?
Ni /
) y subDelimitersToEncode
(es decir, !
, $
, &
, ''
, (
, )
, *
, +
subDelimitersToEncode
;
, y =
). Esta es la implementación correcta (aunque podría debatir sobre la eliminación de ?
Y /
), aunque bastante intrincada. Quizás CFURLCreateStringByAddingPercentEscapes
sea más directo / eficiente.
Si no desea utilizar clases de terceros, la siguiente es la forma en que configura el cuerpo del mensaje ...
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 publicaciones
Todos los cambios a NSMutableURLRequest
deben realizarse antes de llamar a NSURLConnection
.
Veo este problema mientras copio y TCPMon
el código anterior y ejecuto TCPMon
y veo que la solicitud es GET
lugar de la POST
esperada.
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];
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]];