使用 NSURLSession 发送 POST 请求 [英] Send POST request using NSURLSession

查看:65
本文介绍了使用 NSURLSession 发送 POST 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新:找到解决方案.您可以在文章末尾阅读.

Update: Solution found. You can read it at the end of the post.

我正在尝试使用 NSURLSession 对远程 REST API 执行 POST 请求.这个想法是使用两个参数发出请求:deviceIdtextContent.

I'm trying to perform a POST request to a remote REST API using NSURLSession. The idea is to make a request with two parameters: deviceId and textContent.

问题是服务器无法识别这些参数.服务器部分工作正常,因为我已经使用 POSTMAN for Google Chrome 发送了一个 POST 并且它工作得很好.

The problem is that those parameters are not recognized by the server. The server part works correctly because I've sent a POST using POSTMAN for Google Chrome and it worked perfectly.

这是我现在使用的代码:

This is the code I'm using right now:

NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
NSString *textContent = @"New note";
NSString *noteDataString = [NSString stringWithFormat:@"deviceId=%@&textContent=%@", deviceID, textContent];

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = @{
                                               @"api-key"       : @"API_KEY",
                                               @"Content-Type"  : @"application/json"
                                               };
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPMethod = @"POST";
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    // The server answers with an error because it doesn't receive the params
}];
[postDataTask resume];

我已经用 NSURLSessionUploadTask 尝试了相同的过程:

I've tried the same procedure with a NSURLSessionUploadTask:

// ...
NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[noteDataString dataUsingEncoding:NSUTF8StringEncoding] completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    // The server answers with an error because it doesn't receive the params
}];
[uploadTask resume];

有什么想法吗?

我的方法的问题是我在所有请求中都发送了不正确的 Content-Type 标头.因此,代码正常工作所需的唯一更改是删除 Content-Type = application/json HTTP 标头.所以正确的代码是这样的:

The problem with my approach was that I was sending the incorrect Content-Type header with all my requests. So the only change needed for the code to work correctly is to remove the Content-Type = application/json HTTP header. So the correct code would be this:

NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
NSString *textContent = @"New note";
NSString *noteDataString = [NSString stringWithFormat:@"deviceId=%@&textContent=%@", deviceID, textContent];

NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = @{
                                               @"api-key"       : @"API_KEY"
                                               };
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration];
NSURL *url = [NSURL URLWithString:@"http://url_to_manage_post_requests"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding];
request.HTTPMethod = @"POST";
NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    // The server answers with an error because it doesn't receive the params
}];
[postDataTask resume];

与其他参数一起发送图像

如果您需要使用 NSURLSession 将图像与其他参数一起发布,这里有一个示例:

Sending images along with other parameters

If you need to post images along with other parameters using NSURLSession here you have an example:

NSString *deviceID = [[NSUserDefaults standardUserDefaults] objectForKey:@"deviceID"];
NSString *textContent = @"This is a new note";

// Build the request body
NSString *boundary = @"SportuondoFormBoundary";
NSMutableData *body = [NSMutableData data];
// Body part for "deviceId" parameter. This is a string.
[body appendData:[[NSString stringWithFormat:@"--%@
", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"

", @"deviceId"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@
", deviceID] dataUsingEncoding:NSUTF8StringEncoding]];
// Body part for "textContent" parameter. This is a string.
[body appendData:[[NSString stringWithFormat:@"--%@
", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"

", @"textContent"] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"%@
", textContent] dataUsingEncoding:NSUTF8StringEncoding]];
// Body part for the attachament. This is an image.
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"ranking"], 0.6);
if (imageData) {
    [body appendData:[[NSString stringWithFormat:@"--%@
", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name="%@"; filename="image.jpg"
", @"image"] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Type: image/jpeg

" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:imageData];
    [body appendData:[[NSString stringWithFormat:@"
"] dataUsingEncoding:NSUTF8StringEncoding]];
}
[body appendData:[[NSString stringWithFormat:@"--%@--
", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

// Setup the session
NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfiguration.HTTPAdditionalHeaders = @{
                                               @"api-key"       : @"55e76dc4bbae25b066cb",
                                               @"Accept"        : @"application/json",
                                               @"Content-Type"  : [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary]
                                               };

// Create the session
// We can use the delegate to track upload progress
NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:nil];

// Data uploading task. We could use NSURLSessionUploadTask instead of NSURLSessionDataTask if we needed to support uploads in the background
NSURL *url = [NSURL URLWithString:@"URL_TO_UPLOAD_TO"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
request.HTTPMethod = @"POST";
request.HTTPBody = body;
NSURLSessionDataTask *uploadTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    // Process the response
}];
[uploadTask resume];

推荐答案

您可以尝试使用 NSDictionary 作为参数.以下将正确地将参数发送到 JSON 服务器.

You could try using a NSDictionary for the params. The following will send the parameters correctly to a JSON server.

NSError *error;

NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSURL *url = [NSURL URLWithString:@"[JSON SERVER"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:60.0];

[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];

[request setHTTPMethod:@"POST"];
NSDictionary *mapData = [[NSDictionary alloc] initWithObjectsAndKeys: @"TEST IOS", @"name",
                     @"IOS TYPE", @"typemap",
                     nil];
NSData *postData = [NSJSONSerialization dataWithJSONObject:mapData options:0 error:&error];
[request setHTTPBody:postData];


NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

}];

[postDataTask resume];

希望这会有所帮助(我正在尝试使用上述内容对 CSRF 真实性问题进行排序 - 但它确实发送了 NSDictionary 中的参数).

Hope this helps (I'm trying to sort a CSRF authenticity issue with the above - but it does send the params in the NSDictionary).

这篇关于使用 NSURLSession 发送 POST 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆