Dołącz dane do żądania POST NSURLRequest


83

Jak dołączyć dane do istniejącego POST NSURLRequest? Muszę dodać nowy parametr userId=2323.


3
Opisz swoje pytanie jakimś kodem.
— Tirth

Odpowiedzi:


192

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


2
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.

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];

12

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 precentEscapeStringmetoda 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 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 .
— 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]];

8

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.


1

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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.