【发布时间】:2014-01-06 18:09:12
【问题描述】:
类似于this issue。
使用 AFNetworking 2.0.3 并尝试使用 AFHTTPSessionManager 的 POST +constructingBodyWithBlock 上传图像。由于未知原因,当向服务器发出请求时,HTTP 帖子正文似乎总是空白。
我在下面子类化 AFHTTPSessionManager(因此使用了[self POST ...]。
我尝试了两种方式构建请求。
方法1:我只是尝试传递参数,然后只添加存在的图像数据。
- (void) createNewAccount:(NSString *)nickname accountType:(NSInteger)accountType primaryPhoto:(UIImage *)primaryPhoto
{
NSString *accessToken = self.accessToken;
// Ensure none of the params are nil, otherwise it'll mess up our dictionary
if (!nickname) nickname = @"";
if (!accessToken) accessToken = @"";
NSDictionary *params = @{@"nickname": nickname,
@"type": [[NSNumber alloc] initWithInteger:accountType],
@"access_token": accessToken};
NSLog(@"Creating new account %@", params);
[self POST:@"accounts" parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
if (primaryPhoto) {
[formData appendPartWithFileData:UIImageJPEGRepresentation(primaryPhoto, 1.0)
name:@"primary_photo"
fileName:@"image.jpg"
mimeType:@"image/jpeg"];
}
} success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"Created new account successfully");
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"Error: couldn't create new account: %@", error);
}];
}
方法2:尝试在block本身中构建表单数据:
- (void) createNewAccount:(NSString *)nickname accountType:(NSInteger)accountType primaryPhoto:(UIImage *)primaryPhoto
{
// Ensure none of the params are nil, otherwise it'll mess up our dictionary
if (!nickname) nickname = @"";
NSLog(@"Creating new account %@", params);
[self POST:@"accounts" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
[formData appendPartWithFormData:[nickname dataUsingEncoding:NSUTF8StringEncoding] name:@"nickname"];
[formData appendPartWithFormData:[NSData dataWithBytes:&accountType length:sizeof(accountType)] name:@"type"];
if (self.accessToken)
[formData appendPartWithFormData:[self.accessToken dataUsingEncoding:NSUTF8StringEncoding] name:@"access_token"];
if (primaryPhoto) {
[formData appendPartWithFileData:UIImageJPEGRepresentation(primaryPhoto, 1.0)
name:@"primary_photo"
fileName:@"image.jpg"
mimeType:@"image/jpeg"];
}
} success:^(NSURLSessionDataTask *task, id responseObject) {
NSLog(@"Created new account successfully");
} failure:^(NSURLSessionDataTask *task, NSError *error) {
NSLog(@"Error: couldn't create new account: %@", error);
}];
}
使用任一方法,当 HTTP 请求到达服务器时,没有 POST 数据或查询字符串参数,只有 HTTP 标头。
Transfer-Encoding: Chunked
Content-Length:
User-Agent: MyApp/1.0 (iPhone Simulator; iOS 7.0.3; Scale/2.00)
Connection: keep-alive
Host: 127.0.0.1:5000
Accept: */*
Accept-Language: en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5
Content-Type: multipart/form-data; boundary=Boundary+0xAbCdEfGbOuNdArY
Accept-Encoding: gzip, deflate
有什么想法吗?还在AFNetworking's github repo 中发布了一个错误。
【问题讨论】:
-
我使用
AFHTTPRequestOperationManager创建了多部分请求,它运行良好,但是当我使用几乎相同的AFHTTPSessionManager时,它失败了。AFHTTPSessionManager内部似乎有问题。 -
这成功了@Rob,现在将问题悬而未决,但这绝对闻起来像一个错误。
-
你试过查看
task.response吗?我的返回statusCode为 406(但来自AFHTTPRequestOperationManager的相同请求很好)。 -
我的返回
401 Unauthorized,因为access_token没有随请求一起发送。 406 error 听起来很奇怪。显然,您的服务器担心它对未处理客户端的响应。您是否在请求上设置了任何特殊的 HTTP 标头? -
没有。我的客户端代码与上面的第一个示例完全相同。 (我正在测试您的代码。)我添加的唯一内容是明确指定请求和响应序列化程序分别为
AFHTTPRequestSerializer和AFHTTPResponseSerializer。同样的请求(以及序列化程序的使用)与AFHTTPRequestOperationManager一起工作得很好。我正在调试两个 AFNetworking 管理器类,看看是否能看到两者之间差异的根源。
标签: ios objective-c afnetworking afnetworking-2