Додайте дані до запиту 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.