更新: 找到解决方案。您可以在文章末尾阅读。
我正在尝试使用 对远程 REST API 执行 POST 请求NSURLSession。这个想法是使用两个参数发出请求:deviceId和textContent。
NSURLSession
deviceId
textContent
问题是服务器无法识别这些参数。服务器部分工作正常,因为我已经使用 POSTMAN for Google Chrome 发送了一个 POST 并且它工作得很好。
这是我现在正在使用的代码:
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:
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/jsonHTTP 标头。所以正确的代码是这样的:
Content-Type
Content-Type = application/json
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此处发布图像以及其他参数,您有一个示例:
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:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"deviceId"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"%@\r\n", deviceID] dataUsingEncoding:NSUTF8StringEncoding]]; // Body part for "textContent" parameter. This is a string. [body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", @"textContent"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"%@\r\n", 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:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"image.jpg\"\r\n", @"image"] dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:[@"Content-Type: image/jpeg\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; [body appendData:imageData]; [body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]]; } [body appendData:[[NSString stringWithFormat:@"--%@--\r\n", 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 服务器。
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 中发送参数)。