Додайте дані до запиту POST NSURLRequest


83

Як ви додаєте дані до існуючих POST NSURLRequest? Мені потрібно додати новий параметр userId=2323.


3
Будь ласка, опишіть своє запитання кодом.
Tirth,

Відповіді:


192

Якщо ви не хочете використовувати сторонні класи, тоді наступне, як ви встановлюєте тіло повідомлення ...

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

Просто додайте пару ключ / значення до рядка публікації


2
Мені потрібно додати новий параметр до існуючого NSURLRequest, а не створювати новий запит. Я вважаю, що його потрібно спочатку перетворити на NSMutableURLRequest. Я не знаю, як отримати існуючі дані POST.
Тім,

1
Іншими словами, як отримати postString існуючого запиту?
Тім,

1
Ви можете отримати доступ до - (NSData *) HTTPBody, який ви можете закодувати в NSString, пари ключ / значення
Саймон Лі

Наявні дані повідомлення кодуються в UTF8, як у вашому прикладі. Як я можу змінити кодування? Тоді створити новий рядок з новими параметрами? потім закодуйте нові дані пошти
Тім,

1
Це повинно працювати, але наразі я не можу його перевірити .... NSMutableString * existingPost = [[NSMutableString alloc] initWithData: [req HTTPBody] кодування: NSUTF8StringEncoding]; [існуючийФормат додавання публікації: @ "&% @ =% @", @ "ім'я", @ "Locassa"];
Саймон Лі

16

Усі зміни до NSMutableURLRequestобов’язкового внесення потрібно зробити перед дзвінком NSURLConnection.

Я бачу цю проблему, коли копіюю та вставляю наведений вище код і запускаю TCPMonі бачу, що запит GETзамість очікуваного 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

Попередні дописи про формування POSTзапитів є переважно правильними (додайте параметри до основного тексту, а не до URL-адреси). Але якщо є шанс, що вхідні дані містять будь-які зарезервовані символи (наприклад, пробіли, амперсанд та знак плюс), тоді вам потрібно буде обробляти ці зарезервовані символи. А саме, вам слід відсотково уникнути введення.

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

Де precentEscapeStringметод визначається наступним чином:

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

Зауважте, існував багатообіцяючий NSStringметод stringByAddingPercentEscapesUsingEncoding(на даний момент застарілий), який робить щось дуже подібне, але протистоїть спокусі використовувати його. Він обробляє деякі символи (наприклад, пробіл), але не деякі інші (наприклад, символи +або &).

Сучасний еквівалент є stringByAddingPercentEncodingWithAllowedCharacters, але, знову ж таки, не варто спокушатись його використовувати URLQueryAllowedCharacterSet, оскільки це також дозволяє +та &проходить без змін. Ці два символи дозволені в ширшому "запиті", але якщо ці символи з'являються в межах значення в запиті, вони повинні бути екранованими. Технічно ви можете або використовувати, URLQueryAllowedCharacterSetщоб створити змінний набір символів і видалити кілька символів, які вони туди включили, або створити власний набір символів з нуля.

Наприклад, якщо ви подивитеся на Alamofire в кодуванні параметрів , вони приймають , URLQueryAllowedCharacterSetа потім видалити generalDelimitersToEncode(який включає в себе символи #, [, ], і @, а з - за історичною помилкою в деяких старих веб - серверів, ні ?ні /) і subDelimitersToEncode(тобто !, $, &, ', (, ), *, +, ,, ;, і =). Це правильна реалізація (хоча ви можете обговорити видалення ?та /), хоч і досить заплутано. Можливо, CFURLCreateStringByAddingPercentEscapesє більш прямим / ефективним.


Правда stringByAddingPercentEscapesUsingEncoding:, але stringByAddingPercentEncodingWithAllowedCharacters:чудово працює з кожним персонажем. Приклад: URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Алехандро Котілла

@AlejandroDavidCotillaRojas - Ви можете використовувати stringByAddingPercentEncodingWithAllowedCharacters, але не можете використовувати URLQueryAllowedCharacterSet, оскільки це включає в себе +і &(це дозволені символи в ширшому запиті, але якщо ці символи з'являються в межах значення в запиті, вони повинні бути екранованими, чого цей набір символів не зробить ). Отже, ви можете або використовувати, URLQueryAllowedCharacterSetщоб створити змінний набір символів і видалити кілька символів, які вони туди включили, або створити власний набір символів з нуля. Або використовувати CFURLCreateStringByAddingPercentEscapes.
Роб

Чудова відповідь, дійсно обгрунтовує використання Alamofire, щоб уникнути всієї цієї глибини!
Ден Розенстарк

Враховуючи те, що CFURLCreateStringByAddingPercentEscapesзараз застаріло, ви дійсно повинні створити відповідний набір символів самостійно. Див. Stackoverflow.com/a/54742187/1271826 .
Роб

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

Приклад коду, наведеного вище, був для мене дуже корисним, однак (як вже було натякнуто вище), я думаю, вам потрібно NSMutableURLRequestскоріше використовувати , ніж NSURLRequest. У теперішньому вигляді я не міг змусити його відповісти на setHTTPMethodдзвінок. Зміна типу зафіксовано.


1

Той, хто шукає швидкого рішення

let url = NSURL(string: "http://www.apple.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPBody = "company=Locassa&quality=AWESOME!".dataUsingEncoding(NSUTF8StringEncoding)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.