xcode Base64 Over HTTP POST 丢失数据(Objective-C)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14802715/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Base64 Over HTTP POST losing data (Objective-C)
提问by Jacob Clark
I currently have a HTTP POST Request and a Base64 Encoding Library, I encode my image to B64 then send it over HTTP via the POST method.
我目前有一个 HTTP POST 请求和一个 Base64 编码库,我将我的图像编码为 B64,然后通过 POST 方法通过 HTTP 发送它。
I output the Base64 to XCodes console, copy and paste it and it works perfectly. Although the Base64 I store within the Database (MongoDB, Plain Text File etc) always comes out corrupt on the other end.
我将 Base64 输出到 XCodes 控制台,复制并粘贴它,它运行良好。尽管我存储在数据库中的 Base64(MongoDB、纯文本文件等)总是在另一端出现损坏。
Working Version (Copied and Pasted from XCode): http://dontpanicrabbit.com/api/working.phpBroken Version (From MongoDB Database): http://dontpanicrabbit.com/api/grabimage.php
工作版本(从 XCode 复制和粘贴):http: //dontpanicrabbit.com/api/working.php损坏版本(来自 MongoDB 数据库):http: //dontpanicrabbit.com/api/grabimage.php
If you view the source you'll notice they are the same but there is added whitespace into the broken version.
如果您查看源代码,您会注意到它们是相同的,但在损坏的版本中添加了空格。
The Objective-C code I am using is:
我使用的 Objective-C 代码是:
MyImage.image = [info objectForKey:UIImagePickerControllerOriginalImage];
NSData *imageData = UIImageJPEGRepresentation(MyImage.image, 0);
[Base64 initialize];
NSString *encoded = [Base64 encode:imageData];
NSString *urlPOST = encoded;
//NSLog(@"%@",encoded);
NSString *varyingString1 = @"picture=";
NSString *varyingString2 = urlPOST;
NSString *post = [NSString stringWithFormat: @"%@%@", varyingString1, varyingString2];
NSLog(@"%@", post);
//NSString *post = @"image=%@",urlPOST;
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:@"url/api/insertimage.php"]];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:postData];
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];
NSString *strResult = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
PHP -> MongoDB Storage
PHP -> MongoDB 存储
<?php
try {
// open connection to MongoDB server
$conn = new Mongo('localhost');
// access database
$db = $conn->dablia;
// access collection
$collection = $db->images;
// insert a new document
$item = array(
'picture' => $_POST['picture']
);
$collection->insert($item);
echo 'Inserted document with ID: ' . $item['_id'];
// disconnect from server
$conn->close();
} catch (MongoConnectionException $e) {
die('Error connecting to MongoDB server');
} catch (MongoException $e) {
die('Error: ' . $e->getMessage());
}
?>
Output Code:
输出代码:
<?php
try {
// open connection to MongoDB server
$conn = new Mongo('localhost');
// access database
$db = $conn->dablia;
// access collection
$collection = $db->images;
// execute query
// retrieve all documents
$cursor = $collection->find();
// iterate through the result set
// print each document
foreach ($cursor as $obj) {
echo '<img src="data:image/jpeg;base64,'.trim($obj['picture']).'">';
}
// disconnect from server
$conn->close();
} catch (MongoConnectionException $e) {
die('Error connecting to MongoDB server');
} catch (MongoException $e) {
die('Error: ' . $e->getMessage());
}
?>
I have no idea why I seem to be corrupting over POST?
我不知道为什么我似乎在 POST 上损坏了?
回答by imaginaryboy
The problem is exactly what I suggested in my first comment. That is, base64 encoded data can contain '+' characters. In x-www-form-urlencoded data the receiver knows that '+' is an encoding of a space character. Thus since you aren't URL encoding your base64 value, any instances of '+' will cause the data to be corrupted when received.
问题正是我在第一条评论中所建议的。也就是说,base64 编码的数据可以包含“+”字符。在 x-www-form-urlencoded 数据中,接收者知道“+”是空格字符的编码。因此,由于您不是对 base64 值进行 URL 编码,因此任何 '+' 实例都会导致接收到的数据损坏。
The '+' characters in your initial data are turning into ' ' when received and stored. When you then output that value, it is invalid base64 encoded data.
初始数据中的 '+' 字符在接收和存储时变成了 ' '。当您输出该值时,它是无效的 base64 编码数据。
If you examine the source of your working vs. non-working examples you'll see that the whitespace exists EXACTLY where there is a '+' in the original Base64 encoded value. Any newlines you're seeing are because whatever you're viewing the source in is wrapping lines at a ' ' character.
如果您检查工作示例与非工作示例的来源,您会发现空格完全存在于原始 Base64 编码值中有“+”的位置。您看到的任何换行符都是因为您正在查看源代码的任何内容都是在 ' ' 字符处换行。
In your iOS code you need to properly encode the base64 encoded value, in your case all you really need to do is percent encode the '+' characters.
在您的 iOS 代码中,您需要正确编码 base64 编码的值,在您的情况下,您真正需要做的就是对“+”字符进行百分比编码。
EDIT to add, in response to comment:
编辑添加,以回应评论:
post = [post stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"];