2013-02-10 41 views
16

我目前有一個HTTP POST請求和一個Base64編碼庫,我將圖像編碼到B64,然後通過POST方法通過HTTP發送它。Base64 Over HTTP POST丟失數據(Objective-C)

我輸出Base64到XCodes控制檯,複製並粘貼它,它完美的工作。儘管數據庫中的Base64 I存儲(MongoDB,純文本文件等)總是在另一端損壞。

工作版本(複製和粘貼的XCode):http://dontpanicrabbit.com/api/working.php 破碎版本(從MongoDB的數據庫):http://dontpanicrabbit.com/api/grabimage.php

如果您查看源代碼,你會發現它們是相同的,但有加空格到破版。

我使用的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的存儲

<?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()); 
    } 
?> 

輸出代碼:

<?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()); 
} 
?> 

我不知道爲什麼我似乎是通過POST腐敗?

+0

Base64編碼數據可以包含 '+' 字符。在x-www-form-urlencoded數據中(因爲我希望你的POST數據是)接收者知道'+'是空格字符的編碼。因此,由於您不是URL編碼base64值,任何「+」實例都會導致數據在收到時被破壞。這可能是也可能不是你正在經歷的,但你會在某個時候體驗它。 – imaginaryboy 2013-02-10 21:40:21

+0

我認爲這個問題是空格當PHP輸出,我已經比較兩個工作(從轉換直接複製粘貼)和PHP的數據庫版本,似乎有PHP空間的源代碼中的空白和行返回,這導致它打破,我已經嘗試過修剪()周圍的回聲但無濟於事 – 2013-02-10 21:45:35

+0

因此,你的$ _POST ['圖片']的價值是相同的,你從iOS應用程序登錄?另外,如果您認爲問題出在PHP中輸出值時,也許您應該在您的問題中包含該代碼? – imaginaryboy 2013-02-10 21:55:19

回答

40

問題正是我在第一條評論中提出的。也就是說,base64編碼的數據可以包含'+'字符。在x-www-form-urlencoded數據中,接收者知道'+'是空格字符的編碼。因此,由於您不是URL編碼base64值,任何「+」實例都會導致數據在收到時被破壞。

初始數據中的'+'字符在接收和存儲時會變成'''。當你輸出該值時,它是無效的base64編碼數據。

如果您檢查您的工作與非工作示例的來源,您會發現空白存在正確原始Base64編碼值中存在「+」的位置。你看到的任何換行符都是因爲無論你在查看源代碼,都是用一個''字符包裝行。

在你的iOS代碼中,你需要正確編碼base64編碼值,在你的情況下,你真正需要做的是百分比編碼'+'字符。

EDIT添加,響應於評價:

post = [post stringByReplacingOccurrencesOfString:@"+" withString:@"%2B"]; 
+0

剛剛在這之前使用'post = [post stringByReplacingOccurrencesOfString:@「+」withString:@「%」];'現在這個字符串並沒有存儲在Mongo裏面,儘管XCode在它的控制檯裏面把它夾在裏面。 PHP echoch out Null,我在VaryString下面的連接行下添加了行1&2 – 2013-02-10 22:32:45

+0

編碼爲「+」的百分比是「%2B」。見上面編輯的答案。 – imaginaryboy 2013-02-10 22:51:05

+0

謝謝,工作像一個絕對的魅力!救星。 – 2013-02-10 22:59:13