NSMutableURLRequest 发送部分的 POST 请求体

3
我使用NSMutableURLRequest将一个base64编码的图片作为post请求的一部分发送到服务器。我在日志中记录的post请求正文和服务器收到的内容不一样。服务器似乎获得了一个被截断的版本,好像连接在中途就中止了。以下是代码:
NSString *dataStr = [NSString stringWithFormat:@"request_data=%@",reqStr];
NSLog(@"datastr is %@",dataStr);
NSData *dataForUrl = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
NSLog(@"nsdata length is: %i",[dataForUrl length]);
[urlRequest setHTTPBody:dataForUrl];
[urlRequest setValue:[NSString stringWithFormat:@"%d", [dataForUrl length]] forHTTPHeaderField:@"Content-Length"];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *res, NSData *data, NSError *err) {
    // ... 
}

第一个日志语句显示了正确的数据。我甚至把字符串的base64部分拿到http://www.motobit.com/util/base64-decoder-encoder.asp解码成为jpg,这是正确的图像。第二个日志语句表明长度是正确的(例如,当图片大小为422480时,长度为422624)。
我找不到连接细节或数据有任何问题。手机建立了连接,发送了一些数据,然后手机要么停止发送,要么服务器停止接收。是什么原因导致这种情况?
编辑:示例数据链接http://pastebin.com/BS9HjKhg 编辑2:服务器或iOS将图像中的“+”转换为空格。我会在找到正确发送方法后发布答案。

您的客户端连接是否以某种错误或成功结束? - sergio
我实际上从服务器那里得到了一个成功的响应,这意味着它获取了数据,并且至少有一些数据存在。由于图像数据位于字符串末尾,因此它被截断,服务器会根据接收到的base64字符串大小给出各种错误。 - brodney
1
我怀疑这与服务器有关... 服务器日志有没有显示任何信息? - sergio
它确实显示了一些信息,但长度超过255个字符的条目将被截断。通常错误是base64字符串的无效长度,假设传输了超过201个字符。否则,它只接受数据并在后续的仪表板中显示图像错误。我需要使用任何http头吗? - brodney
2个回答

4

我能够比较来自服务器的完整样本和xcode日志,发现+被转换为[space]。由于这是唯一出现问题的字符,并且iOS中的url编码存在缺陷,所以我只是做了

NSString *dataStr = [NSString stringWithFormat:@"request_data=%@",[reqStr stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"]];

服务器再次接受它们。我仍然不确定是服务器出了问题还是 iOS 出了问题。其他连接使用相同的 application/x-www-form-urlencoded 作为内容类型,没有任何问题。

如果您需要Swift中更通用的方法,请查看我的答案 https://dev59.com/QEzSa4cB1Zd3GeqPo7e1#57476743 - Henadzi Rabkin

1

我建议使用Nick Lockwood的Base64类将Base64字符串转换为NSData

NSData *dataForUrl = [dataStr dataUsingEncoding:NSUTF8StringEncoding];

这让我有点担心(尤其是在看了Base64如何实现转换之后)...


我刚刚尝试了写入文件和使用NSInputStream,并尝试使用[NSURLConnection sendSynchronousRequest:],结果相同。 - brodney
你所说的“相同结果”是什么意思?你尝试过使用Base64吗?它是否产生与dataUsingEncoding:相同的输出? - sergio
1
事实是,我真的不知道发生了什么。我想也许使用 dataUsingEncoding: 将您的 NSString(其中一部分是 Base64 数据)转换为 NSData 不是正确的方式。可能问题在于您发送的字符串,也许您可以尝试发布其中的一部分... - sergio
在我的问题中添加了示例数据的链接。里面没有敏感信息,因此没有进行修改。您可以将base64部分转换为jpg以查看原始图像。 - brodney
服务器如何知道图像数据从哪里开始?您不应该对字符串的非Base64部分进行URL编码吗? - sergio
波浪号是分隔符,因此它大致读作“ID为524的元素,其值为/9j/4A...”。服务器架构师似乎不熟悉JSON。服务器期望数据按原样提供,但我将尝试进行编码以查看会发生什么。 - brodney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接