Hängen Sie Daten an eine POST NSURLRequest an

82

Wie hängen Sie Daten an eine vorhandene an POST NSURLRequest? Ich muss einen neuen Parameter hinzufügen userId=2323.

Tim
quelle
3
Bitte beschreiben Sie Ihre Frage mit einem Code.
Tirth

Antworten:

191

Wenn Sie keine Klassen von Drittanbietern verwenden möchten, legen Sie den Post-Body wie folgt fest ...

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

Hängen Sie einfach Ihr Schlüssel / Wert-Paar an die Post-Zeichenfolge an

Simon Lee
quelle
2
Ich muss den neuen Parameter zu einer vorhandenen NSURLRequest hinzufügen und keine neue Anfrage erstellen. Ich glaube, es muss zuerst in eine NSMutableURLRequest konvertiert werden. Was ich nicht weiß, ist, wie man die vorhandenen POST-Daten erhält.
Tim
1
Mit anderen Worten, wie erhalten Sie den PostString einer vorhandenen Anfrage?
Tim
1
Sie können auf den - (NSData *) HTTPBody zugreifen, den Sie in ein NSString-Schlüssel / Wert-Paar codieren können
Simon Lee
Die vorhandenen Postdaten werden wie in Ihrem Beispiel in UTF8 codiert. Wie kann ich die Codierung umkehren? Dann einen neuen String mit den neuen Parametern erstellen? dann verschlüsseln Sie die neuen Postdaten
Tim
1
Dies sollte funktionieren, aber ich kann es momentan nicht testen .... NSMutableString * existentPost = [[NSMutableString-Zuweisung] initWithData: [req HTTPBody] encoding: NSUTF8StringEncoding]; [existierende Post appendFormat: @ "&% @ =% @", @ "Name", @ "Locassa"];
Simon Lee
16

Alle Änderungen an NSMutableURLRequestmüssen vor dem Anruf vorgenommen werden NSURLConnection.

Ich sehe dieses Problem, wenn ich den obigen Code kopiere und einfüge TCPMonund die Anforderung GETanstelle der erwarteten ausführe 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
quelle
12

Die vorherigen Beiträge zum Erstellen von POSTAnforderungen sind weitgehend korrekt (fügen Sie die Parameter dem Textkörper und nicht der URL hinzu). Wenn jedoch die Möglichkeit besteht, dass die Eingabedaten reservierte Zeichen enthalten (z. B. Leerzeichen, kaufmännisches Und und Vorzeichen), sollten Sie diese reservierten Zeichen verarbeiten. Sie sollten nämlich der Eingabe prozentual entkommen.

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

Wo die precentEscapeStringMethode wie folgt definiert ist:

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

Beachten Sie, dass es eine vielversprechende NSStringMethode gab stringByAddingPercentEscapesUsingEncoding(die jetzt veraltet ist), die etwas sehr Ähnliches tut, aber der Versuchung widersteht, diese zu verwenden. Es behandelt einige Zeichen (z. B. das Leerzeichen), aber nicht einige der anderen (z. B. +oder &Zeichen).

Das zeitgenössische Äquivalent ist stringByAddingPercentEncodingWithAllowedCharacters, aber auch hier nicht versucht zu sein URLQueryAllowedCharacterSet, da dies auch erlaubt +und &ungehindert passieren kann. Diese beiden Zeichen sind in der umfassenderen "Abfrage" zulässig. Wenn diese Zeichen jedoch in einem Wert in einer Abfrage enthalten sind, müssen sie maskiert werden. Technisch können Sie entweder verwendenURLQueryAllowedCharacterSet einen veränderlichen Zeichensatz erstellen und einige der darin enthaltenen Zeichen entfernen oder Ihren eigenen Zeichensatz von Grund auf neu erstellen.

Zum Beispiel, wenn Sie bei Alamofire der aussehen Parametercodierung , nehmen sie URLQueryAllowedCharacterSetund entfernen generalDelimitersToEncode(die die Zeichen enthält #, [, ], und @, aber wegen eines historischen Fehler in einigen alten Web - Server, weder ?noch /) und subDelimitersToEncode(dh !, $, &, ', (, ), *, +, ,, ;, und =). Dies ist eine korrekte Implementierung (obwohl Sie über das Entfernen von ?und diskutieren könnten /), obwohl sie ziemlich kompliziert ist. Vielleicht CFURLCreateStringByAddingPercentEscapesist direkter / effizienter.

rauben
quelle
Stimmt stringByAddingPercentEscapesUsingEncoding:, stringByAddingPercentEncodingWithAllowedCharacters:funktioniert aber gut mit jedem Charakter. Beispiel: URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Alejandro Cotilla
@AlejandroDavidCotillaRojas - Sie können verwenden stringByAddingPercentEncodingWithAllowedCharacters, aber Sie können nicht verwenden URLQueryAllowedCharacterSet, da dies +und &(diese sind zulässige Zeichen in der breiteren Abfrage, aber wenn diese Zeichen in einem Wert innerhalb einer Abfrage erscheinen, müssen sie maskiert werden, was dieser Zeichensatz nicht tut ). Sie können also entweder URLQueryAllowedCharacterSeteinen veränderlichen Zeichensatz erstellen und einige der darin enthaltenen Zeichen entfernen oder Ihren eigenen Zeichensatz von Grund auf neu erstellen. Oder verwenden CFURLCreateStringByAddingPercentEscapes.
Rob
Tolle Antwort, macht wirklich den Fall für die Verwendung von Alamofire, um all diese Tiefe zu vermeiden!
Dan Rosenstark
Da dies CFURLCreateStringByAddingPercentEscapesjetzt veraltet ist, sollten Sie den entsprechenden Zeichensatz wirklich selbst erstellen. Siehe 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
quelle
8

Der obige Beispielcode war für mich sehr hilfreich, aber (wie oben angedeutet), ich denke, Sie müssen ihn NSMutableURLRequesteher verwenden als NSURLRequest. In der aktuellen Form konnte ich es nicht dazu bringen, auf den setHTTPMethodAnruf zu antworten . Durch Ändern des Typs wurden die Probleme behoben.

David Fulton
quelle
1

Jeder, der nach einer schnellen Lösung sucht

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