Muszę dodać nowy parametr do istniejącego NSURLRequest, a nie tworzyć nowe żądanie. Uważam, że najpierw należy go przekonwertować na NSMutableURLRequest. Nie wiem, jak uzyskać istniejące dane POST.
Tim
1
Czy innymi słowy, w jaki sposób otrzymujesz postString istniejącego żądania?
Tim
1
Możesz uzyskać dostęp do - (NSData *) HTTPBody, które możesz zakodować w NSString, pary klucz / wartość
Simon Lee
Istniejące dane postu są kodowane w UTF8, jak w przykładzie. Jak mogę odwrócić kodowanie? Następnie utworzysz nowy ciąg z nowymi parametrami? następnie zakoduj nowe dane postu
Tim
1
To powinno działać, ale nie mogę tego teraz przetestować .... NSMutableString * existingPost = [[NSMutableString assign] initWithData: [req HTTPBody] encoding: NSUTF8StringEncoding]; [existingPost appendFormat: @ "&% @ =% @", @ "name", @ "Locassa"];
Simon Lee,
16
Wszystkie zmiany w NSMutableURLRequestdomenie należy wprowadzić przed wywołaniemNSURLConnection .
Widzę ten problem, gdy kopiuję i wklejam powyższy kod, uruchamiam TCPMoni widzę, że żądanie jest GETzamiast oczekiwanego POST.
Poprzednie posty dotyczące POSTżądań formowania są w dużej mierze poprawne (dodaj parametry do treści, a nie do adresu URL). Ale jeśli jest jakaś szansa, że dane wejściowe zawierają jakiekolwiek zastrzeżone znaki (np. Spacje, ampersand, znak plus), wtedy będziesz chciał obsłużyć te zastrzeżone znaki. Mianowicie, powinieneś procentowo zmienić dane wejściowe.
//create body of the requestNSString *userid = ...
NSString *encodedUserid = [self percentEscapeString:userid];
NSString *postString = [NSString stringWithFormat:@"userid=%@", encodedUserid];
NSData *postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
//initialize a request from urlNSMutableURLRequest *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];
Gdzie precentEscapeStringmetoda jest zdefiniowana w następujący sposób:
Zauważ, że była obiecująca NSStringmetoda stringByAddingPercentEscapesUsingEncoding(obecnie przestarzała), która robi coś bardzo podobnego, ale opiera się pokusie jej użycia. Obsługuje niektóre znaki (np. Znak spacji), ale nie niektóre inne (np. Znaki +lub &).
Współczesny odpowiednik jest stringByAddingPercentEncodingWithAllowedCharacters, ale znowu nie być skłonny do użytku URLQueryAllowedCharacterSet, jak również pozwala +i &przekazać Niecytowany. Te dwa znaki są dozwolone w ramach szerszego „zapytania”, ale jeśli te znaki pojawiają się w wartości w zapytaniu, muszą zostać zmienione. Technicznie możesz użyćURLQueryAllowedCharacterSet do zbudowania zmiennego zestawu znaków i usunąć kilka postaci, które tam umieścili, lub zbudować własny zestaw znaków od podstaw.
Na przykład, jeśli spojrzeć na Alamofire za kodowanie parametrów , biorą URLQueryAllowedCharacterSet, a następnie usunąć generalDelimitersToEncode(który zawiera znaki #, [, ], i @, ale z powodu historycznego błędu w niektórych starych serwerów WWW, ani ?też nie /) i subDelimitersToEncode(czyli !, $, &, ', (, ), *, +, ,, ;, i =). Jest to poprawna implementacja (choć można debatować nad usunięciem ?i /), chociaż dość zawiła. Być może CFURLCreateStringByAddingPercentEscapesjest bardziej bezpośredni / skuteczny.
Prawda stringByAddingPercentEscapesUsingEncoding:, ale stringByAddingPercentEncodingWithAllowedCharacters:działa dobrze z każdą postacią. Przykład: URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Alejandro Cotilla
@AlejandroDavidCotillaRojas - Możesz używać stringByAddingPercentEncodingWithAllowedCharacters, ale nie możesz używać URLQueryAllowedCharacterSet, ponieważ obejmuje to +i &(są to dozwolone znaki w ramach szerszego zapytania, ale jeśli te znaki pojawiają się w wartości w zapytaniu, muszą być chronione przed ucieczką, czego ten zestaw znaków nie zrobi ). Możesz więc użyć URLQueryAllowedCharacterSetdo zbudowania zmiennego zestawu znaków i usunąć kilka znaków, które tam umieścili, lub zbudować własny zestaw znaków od podstaw. Lub użyj CFURLCreateStringByAddingPercentEscapes.
Rob
Świetna odpowiedź, naprawdę uzasadnia użycie Alamofire, aby uniknąć całej tej głębi!
Dan Rosenstark
Biorąc pod uwagę, że CFURLCreateStringByAddingPercentEscapesjest to przestarzałe, naprawdę powinieneś sam zbudować odpowiedni zestaw znaków. Zobacz stackoverflow.com/a/54742187/1271826 .
Powyższy przykładowy kod był dla mnie bardzo pomocny, jednak (jak wskazano powyżej), myślę, że powinieneś NSMutableURLRequestraczej użyć niż NSURLRequest. W obecnej formie nie mogłem go zmusić do odpowiedzi na setHTTPMethodwezwanie. Zmiana typu naprawiła rzeczy.
Odpowiedzi:
Jeśli nie chcesz korzystać z klas innych firm, możesz ustawić treść posta w następujący sposób ...
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];
Po prostu dołącz swoją parę klucz / wartość do ciągu postu
źródło
Wszystkie zmiany w
NSMutableURLRequest
domenie należy wprowadzić przed wywołaniemNSURLConnection
.Widzę ten problem, gdy kopiuję i wklejam powyższy kod, uruchamiam
TCPMon
i widzę, że żądanie jestGET
zamiast oczekiwanegoPOST
.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];
źródło
Poprzednie posty dotyczące
POST
żądań formowania są w dużej mierze poprawne (dodaj parametry do treści, a nie do adresu URL). Ale jeśli jest jakaś szansa, że dane wejściowe zawierają jakiekolwiek zastrzeżone znaki (np. Spacje, ampersand, znak plus), wtedy będziesz chciał obsłużyć te zastrzeżone znaki. Mianowicie, powinieneś procentowo zmienić dane wejściowe.//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];
Gdzie
precentEscapeString
metoda jest zdefiniowana w następujący sposób:- (NSString *)percentEscapeString:(NSString *)string { NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)string, (CFStringRef)@" ", (CFStringRef)@":/?@!$&'()*+,;=", kCFStringEncodingUTF8)); return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"]; }
Zauważ, że była obiecująca
NSString
metodastringByAddingPercentEscapesUsingEncoding
(obecnie przestarzała), która robi coś bardzo podobnego, ale opiera się pokusie jej użycia. Obsługuje niektóre znaki (np. Znak spacji), ale nie niektóre inne (np. Znaki+
lub&
).Współczesny odpowiednik jest
stringByAddingPercentEncodingWithAllowedCharacters
, ale znowu nie być skłonny do użytkuURLQueryAllowedCharacterSet
, jak również pozwala+
i&
przekazać Niecytowany. Te dwa znaki są dozwolone w ramach szerszego „zapytania”, ale jeśli te znaki pojawiają się w wartości w zapytaniu, muszą zostać zmienione. Technicznie możesz użyćURLQueryAllowedCharacterSet
do zbudowania zmiennego zestawu znaków i usunąć kilka postaci, które tam umieścili, lub zbudować własny zestaw znaków od podstaw.Na przykład, jeśli spojrzeć na Alamofire za kodowanie parametrów , biorą
URLQueryAllowedCharacterSet
, a następnie usunąćgeneralDelimitersToEncode
(który zawiera znaki#
,[
,]
, i@
, ale z powodu historycznego błędu w niektórych starych serwerów WWW, ani?
też nie/
) isubDelimitersToEncode
(czyli!
,$
,&
,'
,(
,)
,*
,+
,,
,;
, i=
). Jest to poprawna implementacja (choć można debatować nad usunięciem?
i/
), chociaż dość zawiła. Być możeCFURLCreateStringByAddingPercentEscapes
jest bardziej bezpośredni / skuteczny.źródło
stringByAddingPercentEscapesUsingEncoding:
, alestringByAddingPercentEncodingWithAllowedCharacters:
działa dobrze z każdą postacią. Przykład:URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
stringByAddingPercentEncodingWithAllowedCharacters
, ale nie możesz używaćURLQueryAllowedCharacterSet
, ponieważ obejmuje to+
i&
(są to dozwolone znaki w ramach szerszego zapytania, ale jeśli te znaki pojawiają się w wartości w zapytaniu, muszą być chronione przed ucieczką, czego ten zestaw znaków nie zrobi ). Możesz więc użyćURLQueryAllowedCharacterSet
do zbudowania zmiennego zestawu znaków i usunąć kilka znaków, które tam umieścili, lub zbudować własny zestaw znaków od podstaw. Lub użyjCFURLCreateStringByAddingPercentEscapes
.CFURLCreateStringByAddingPercentEscapes
jest to przestarzałe, naprawdę powinieneś sam zbudować odpowiedni zestaw znaków. Zobacz stackoverflow.com/a/54742187/1271826 .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]];
źródło
Powyższy przykładowy kod był dla mnie bardzo pomocny, jednak (jak wskazano powyżej), myślę, że powinieneś
NSMutableURLRequest
raczej użyć niżNSURLRequest
. W obecnej formie nie mogłem go zmusić do odpowiedzi nasetHTTPMethod
wezwanie. Zmiana typu naprawiła rzeczy.źródło
Każdy, kto szuka szybkiego rozwiązania
let url = NSURL(string: "http://www.apple.com/") let request = NSMutableURLRequest(URL: url!) request.HTTPBody = "company=Locassa&quality=AWESOME!".dataUsingEncoding(NSUTF8StringEncoding)
źródło