iOS上傳圖像到服務(wù)器,以及服務(wù)器PHP接收的三種方式

1. 將圖片轉(zhuǎn)換為Base64編碼想邦,POST上傳裤纹。PHP將Base64解碼為二進(jìn)制,再寫出文件案狠。

缺點:不能上傳較大的圖片
原因:post 理論上講是沒有大小限制的服傍,HTTP協(xié)議規(guī)范也沒有進(jìn)行大小限制,但實際上post所能傳遞的數(shù)據(jù)量大小取決于服務(wù)器的設(shè)置和內(nèi)存大小骂铁。以php語言來說吹零,上傳文件最大是默認(rèn)是2MB,更改這個值需要更改php.conf的post_max_size這個值拉庵。

// iOS(Swift)
func upload(image: UIImage, url: String) {
    let imageData = UIImageJPEGRepresentation(image, 0.3) // 將圖片轉(zhuǎn)換成jpeg格式的NSData灿椅,壓縮到0.3
    let imageStr = imageData?.base64EncodedStringWithOptions(.Encoding64CharacterLineLength) // 將圖片轉(zhuǎn)換為base64字符串
    let params: NSDictionary = ["file": imageStr!]
    let manager = AFHTTPRequestOperationManager()
    
    // 采用POST的方式上傳,因為POST對長度沒有限制
    manager.POST(url, parameters: params, success: { (_: AFHTTPRequestOperation!, response: AnyObject!) in
        // 成功
    }) { (_: AFHTTPRequestOperation!, _: NSError!) in
        // 失敗
    }
}
<?php
header('Content-type: text/json; charset=UTF-8');

$base64 = $_POST["file"]; // 得到參數(shù)
$img = base64_decode($base64); // 將格式為base64的字符串解碼
$path = "md5(uniqid(rand()))".".jpg"; // 產(chǎn)生隨機(jī)唯一的名字作為文件名
file_put_contents($path, $img); // 將圖片保存到相應(yīng)位置
?>

2.AFNetworking上傳钞支,PHP端通過正常接收網(wǎng)頁上傳方法來接收圖片

static func uploadPortrait(image: UIImage, url: String) {
    let manager = AFHTTPRequestOperationManager()
    
    // fromData: AFN封裝好的http header類茫蛹,可以添加請求體
    manager.POST(url, parameters: [:], constructingBodyWithBlock: { (fromData: AFMultipartFormData!) in
        let pngData = UIImagePNGRepresentation(image)
        // name必須和后臺PHP接收的參數(shù)名相同($_FILES["file"])
        // fileName為圖片名
        fromData.appendPartWithFileData(pngData, name: "file", fileName: "image.png", mimeType: "image/png")      
          
        // let jpegData = UIImageJPEGRepresentation(image, 0.3)
        // fromData.appendPartWithFileData(jpegData, name: "file", fileName: "image.jpg", mimeType: "image/jpeg")
    }, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) in
        // 成功
    }) { (operation: AFHTTPRequestOperation!, error: NSError!) in
        // 失敗
    }   
}
<?php
header('Content-type: text/json; charset=UTF-8' );

/**
 * $_FILES 文件上傳變量,是一個二維數(shù)組烁挟,第一維保存上傳的文件的數(shù)組婴洼,第二維保存文件的屬性,包括類型撼嗓、大小等
 * 要實現(xiàn)上傳文件柬采,必須修改權(quán)限為加入可寫 chmod -R 777 目標(biāo)目錄
 */

// 文件類型限制
// "file"名字必須和iOS客戶端上傳的name一致
if (($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/png")
|| ($_FILES["file"]["type"] == "image/pjpeg"))
// && ($_FILES["file"]["size"] < 20000)) // 小于20k
{
    if ($_FILES["file"]["error"] > 0) {
        echo $_FILES["file"]["error"]; // 錯誤代碼
    } else {           
        $fillname = $_FILES['file']['name']; // 得到文件全名
        $dotArray = explode('.', $fillname); // 以.分割字符串,得到數(shù)組
        $type = end($dotArray); // 得到最后一個元素:文件后綴

        $path = "../portrait/".md5(uniqid(rand())).'.'.$type; // 產(chǎn)生隨機(jī)唯一的名字
        
        move_uploaded_file( // 從臨時目錄復(fù)制到目標(biāo)目錄
          $_FILES["file"]["tmp_name"], // 存儲在服務(wù)器的文件的臨時副本的名稱
          $path);
          
        echo "成功";
    } 
} else {
    echo "文件類型不正確";
}
?>

3.將圖片封裝在Http的請求報文中的請求體(body)中上傳且警。也是AFN上傳的原理

// 使用OC封裝
#import <UIKit/UIKit.h>
@interface RequestPostUploadHelper : NSObject
+ (NSMutableURLRequest *)uploadImage:(NSString*)url uploadImage:(UIImage *)uploadImage params:(NSMutableDictionary *)params;
@end

#import "RequestPostUploadHelper.h"
@implementation RequestPostUploadHelper
+ (NSMutableURLRequest *)uploadImage:(NSString*)url uploadImage:(UIImage *)uploadImage params:(NSMutableDictionary *)params {
    [params setObject:uploadImage forKey:@"file"];
    
    //分界線的標(biāo)識符
    NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
    //根據(jù)url初始化request
    NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
                                                       timeoutInterval:10];
    //分界線 --AaB03x
    NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
    //結(jié)束符 AaB03x--
    NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
    //要上傳的圖片
    UIImage *image=[params objectForKey:@"file"];
    //得到圖片的data
    NSData* data = UIImagePNGRepresentation(image);
    //http body的字符串
    NSMutableString *body=[[NSMutableString alloc]init];
    //參數(shù)的集合的所有key的集合
    NSArray *keys= [params allKeys];
    
    //遍歷keys
    for(int i = 0; i < [keys count]; i++)
    {
        //得到當(dāng)前key
        NSString *key = [keys objectAtIndex:i];
        //如果key不是file粉捻,說明value是字符類型,比如name
        if(![key isEqualToString:@"file"])
        {
            //添加分界線斑芜,換行
            [body appendFormat:@"%@\r\n",MPboundary];
            //添加字段名稱肩刃,換2行
            [body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
            //添加字段的值
            [body appendFormat:@"%@\r\n",[params objectForKey:key]];
        }
    }
    
    ////添加分界線,換行
    [body appendFormat:@"%@\r\n",MPboundary];
    //聲明file字段,文件名為image.png
    [body appendFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"image.png\"\r\n"];
    //聲明上傳文件的格式
    [body appendFormat:@"Content-Type: image/png\r\n\r\n"];
    
    //聲明結(jié)束符:--AaB03x--
    NSString *end=[[NSString alloc] initWithFormat:@"\r\n%@",endMPboundary];
    //聲明myRequestData盈包,用來放入http body
    NSMutableData *myRequestData = [NSMutableData data];
    //將body字符串轉(zhuǎn)化為UTF8格式的二進(jìn)制
    [myRequestData appendData:[body dataUsingEncoding:NSUTF8StringEncoding]];
    //將image的data加入
    [myRequestData appendData:data];
    //加入結(jié)束符--AaB03x--
    [myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
    
    //設(shè)置HTTPHeader中Content-Type的值
    NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
    //設(shè)置HTTPHeader
    [request setValue:content forHTTPHeaderField:@"Content-Type"];
    //設(shè)置Content-Length
    [request setValue:[NSString stringWithFormat:@"%d", [myRequestData length]] forHTTPHeaderField:@"Content-Length"];
    //設(shè)置http body
    [request setHTTPBody:myRequestData];
    //http method
    [request setHTTPMethod:@"POST"];
    
    return request;
}
@end

// 使用
// Swift
static func uploadPortrait(image: UIImage, url:String) {
    // 使用
    let request = RequestPostUploadHelper.uploadImage(url, uploadImage: image, params: [:])
    // 異步網(wǎng)絡(luò)請求
    NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue()) { (response: NSURLResponse?, data: NSData?, error: NSError?) in
        if error != nil {
            // 失敗
        } else {
            // 成功
        }
    }
}
<?php
// PHP代碼和上一步相同
?>

4.iOS圖片轉(zhuǎn)換為NSData沸呐,通過POST上傳。PHP接收POST參數(shù)续语,將NSData的16進(jìn)制編碼轉(zhuǎn)換為PHP支持的二進(jìn)制垂谢,再寫出文件保存

暫時沒有找到辦法,PHP接收到16進(jìn)制編碼后疮茄,使用算法轉(zhuǎn)換為二進(jìn)制后無法輸出圖片滥朱。在這里拋磚引玉,如果有同學(xué)知道解決辦法力试,希望簡信或者評論徙邻。

5.二進(jìn)制POST上傳。PHP直接將數(shù)據(jù)保存為圖片

暫時沒有找到辦法畸裳,iOS端使用NSData的getBytes無法轉(zhuǎn)換為二進(jìn)制缰犁。在這里拋磚引玉,如果有同學(xué)知道解決辦法怖糊,希望簡信或者評論帅容。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市伍伤,隨后出現(xiàn)的幾起案子并徘,更是在濱河造成了極大的恐慌,老刑警劉巖扰魂,帶你破解...
    沈念sama閱讀 217,185評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麦乞,死亡現(xiàn)場離奇詭異,居然都是意外死亡劝评,警方通過查閱死者的電腦和手機(jī)姐直,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,652評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蒋畜,“玉大人声畏,你說我怎么就攤上這事∫龀桑” “怎么了插龄?”我有些...
    開封第一講書人閱讀 163,524評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長佣渴。 經(jīng)常有香客問我,道長初斑,這世上最難降的妖魔是什么辛润? 我笑而不...
    開封第一講書人閱讀 58,339評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上砂竖,老公的妹妹穿的比我還像新娘真椿。我一直安慰自己,他們只是感情好乎澄,可當(dāng)我...
    茶點故事閱讀 67,387評論 6 391
  • 文/花漫 我一把揭開白布突硝。 她就那樣靜靜地躺著,像睡著了一般置济。 火紅的嫁衣襯著肌膚如雪解恰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,287評論 1 301
  • 那天浙于,我揣著相機(jī)與錄音护盈,去河邊找鬼。 笑死羞酗,一個胖子當(dāng)著我的面吹牛腐宋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播檀轨,決...
    沈念sama閱讀 40,130評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼胸竞,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了参萄?” 一聲冷哼從身側(cè)響起卫枝,我...
    開封第一講書人閱讀 38,985評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎拧揽,沒想到半個月后剃盾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,420評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡淤袜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,617評論 3 334
  • 正文 我和宋清朗相戀三年痒谴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铡羡。...
    茶點故事閱讀 39,779評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡积蔚,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出烦周,到底是詐尸還是另有隱情尽爆,我是刑警寧澤,帶...
    沈念sama閱讀 35,477評論 5 345
  • 正文 年R本政府宣布读慎,位于F島的核電站漱贱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏夭委。R本人自食惡果不足惜幅狮,卻給世界環(huán)境...
    茶點故事閱讀 41,088評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧崇摄,春花似錦擎值、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,716評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至厕氨,卻和暖如春进每,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背腐巢。 一陣腳步聲響...
    開封第一講書人閱讀 32,857評論 1 269
  • 我被黑心中介騙來泰國打工品追, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人冯丙。 一個月前我還...
    沈念sama閱讀 47,876評論 2 370
  • 正文 我出身青樓肉瓦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親胃惜。 傳聞我的和親對象是個殘疾皇子泞莉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,700評論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)船殉,斷路器鲫趁,智...
    卡卡羅2017閱讀 134,654評論 18 139
  • php.ini設(shè)置,上傳大文件: post_max_size = 128Mupload_max_filesize ...
    bycall閱讀 6,756評論 3 64
  • 該文章屬于<簡書 — Timhbw>原創(chuàng),轉(zhuǎn)載請注明: <簡書社區(qū) — Timhbw>http://www.jia...
    伯虔閱讀 17,104評論 3 158
  • iOS開發(fā)系列--網(wǎng)絡(luò)開發(fā) 概覽 大部分應(yīng)用程序都或多或少會牽扯到網(wǎng)絡(luò)開發(fā)利虫,例如說新浪微博挨厚、微信等,這些應(yīng)用本身可...
    lichengjin閱讀 3,658評論 2 7
  • 客戶端JavaScript的作用: 客戶端數(shù)據(jù)計算 表單輸入驗證 瀏覽器事件的觸發(fā)和處理 網(wǎng)頁特殊顯示效果制作 服...
    喵小姐貓貓閱讀 194評論 0 0