Как вы добавляете данные к существующему POST
NSURLRequest
? Мне нужно добавить новый параметр userId=2323
.
Добавить данные в POST NSURLRequest
Ответы (5)
Если вы не хотите использовать сторонние классы, то вот как вы устанавливаете тело сообщения...
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];
Просто добавьте пару ключ/значение в строку сообщения.
initWithRequest
запускает запрос и возвращает ссылку NSURLConnection
, если она вам нужна (и вы можете проверить, что это не nil
, чтобы убедиться, что запрос запущен нормально).
- person Rob; 07.01.2015
NSURLConnectionDataDelegate
. И, конечно же, вы должны в процентах экранировать значения, которые вы вставляете в свой HTTPBody
.
- person Rob; 07.01.2015
Все изменения в 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];
Предыдущие посты о формировании 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]];
- person Alejandro Cotilla; 06.02.2016
stringByAddingPercentEncodingWithAllowedCharacters
, но вы не можете использовать URLQueryAllowedCharacterSet
, так как это включает +
и &
(это разрешенные символы в более широком запросе, но если эти символы появляются внутри значения в запросе, они должны экранироваться, что и этот набор символов не пойдет). Таким образом, вы можете либо использовать URLQueryAllowedCharacterSet
для создания изменяемого набора символов и удалить несколько символов, которые они туда включили, либо создать свой собственный набор символов с нуля. Или используйте CFURLCreateStringByAddingPercentEscapes
.
- person Rob; 06.02.2016
CFURLCreateStringByAddingPercentEscapes
теперь устарел, вам действительно следует создать соответствующий набор символов самостоятельно. См. stackoverflow.com/a/54742187/1271826.
- person Rob; 18.02.2019
Приведенный выше пример кода был действительно полезен для меня, однако (как было указано выше), я думаю, вам нужно использовать NSMutableURLRequest
, а не NSURLRequest
. В его нынешнем виде я не мог заставить его ответить на вызов setHTTPMethod
. Изменение типа исправило ситуацию.
Любой, кто ищет быстрое решение
let url = NSURL(string: "http://www.apple.com/")
let request = NSMutableURLRequest(URL: url!)
request.HTTPBody = "company=Locassa&quality=AWESOME!".dataUsingEncoding(NSUTF8StringEncoding)