将数据附加到POST NSURLRequest


83

如何将数据附加到现有数据POST NSURLRequest?我需要添加一个新参数userId=2323


3
请用一些代码描述您的问题。
2011年

Answers:


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数据。
蒂姆(Tim)

1
换句话说,您如何获取现有请求的postString?
蒂姆(Tim)

1
您可以访问-(NSData *)HTTPBody,您可以将其编码为NSString,键/值对
Simon Lee,

如您的示例所示,现有的帖子数据以UTF8编码。如何反转编码?然后使用新参数创建一个新字符串?然后对新的帖子数据进行编码
蒂姆(Tim)

1
应该可以工作,但是我暂时无法对其进行测试。[existingPost appendFormat:@“&%@ =%@”,@“名称”,@“ 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(包括文字#[],和@,但由于在一些旧的Web服务器一个历史错误,既不?也没有/)和subDelimitersToEncode(即!$&'()*+,;,和=)。这是正确的实现方式(尽管您可能会争论删除?/),尽管过程非常复杂。也许CFURLCreateStringByAddingPercentEscapes更直接/有效。


正确stringByAddingPercentEscapesUsingEncoding:,但stringByAddingPercentEncodingWithAllowedCharacters:适用于每个角色。示例: URLString = [URLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
Alejandro Cotilla

@AlejandroDavidCotillaRojas-可以使用stringByAddingPercentEncodingWithAllowedCharacters,但不能使用URLQueryAllowedCharacterSet,因为其中包括+&(这些字符在更广泛的查询中是允许的字符,但是如果这些字符出现在查询的值内,则必须对其进行转义,而该字符集将不会)。因此,您既可以URLQueryAllowedCharacterSet用来构建可变的字符集并删除其中包含的一些字符,也可以从头开始构建自己的字符集。或使用CFURLCreateStringByAddingPercentEscapes
罗布

很好的答案,确实有必要使用Alamofire来避免所有这些深度!
Dan Rosenstark

鉴于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)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.