AF帶來(lái)的血案


已上圖是AF源碼截圖,基于表單的形式上傳。使用的是multipart/form-data發(fā)送文件。
Content-Type必須是multipart/form-data
原理分析
以multipart/form-data編碼的POST請(qǐng)求格式與application/x-www-form-urlencoded完全不同.
其中application/x-www-form-urlencoded提交的數(shù)據(jù)按照 key1=val1&key2=val2 的方式進(jìn)行編碼,key 和 val 都進(jìn)行了 URL 轉(zhuǎn)碼。然而multipart/form-data是這樣的形式:
key1 = val1
key2 = vals
關(guān)于 multipart/form-data 的詳細(xì)定義,請(qǐng)前往 rfc1867 查看。http://www.ietf.org/rfc/rfc1867.txt
例子
<pre>
POST http://www.example.com HTTP/1.1
Content-Type:multipart/form-data; boundary=XXX
此處有有空格*
--XXX
Content-Disposition: form-data; name="text"
title
--XXX
Content-Disposition: form-data; name="file"; filename="chrome.png"
Content-Type: image/png
此處有有空格*
PNG ... content of chrome.png ...
--XXX
</pre>
例子說(shuō)明
首先生成了一個(gè) boundary=XXX 用于分割不同的字段,為了避免與正文內(nèi)容重復(fù),boundary 可能會(huì)很長(zhǎng)很復(fù)雜。然后 Content-Type 里指明了數(shù)據(jù)是以 multipart/form-data 來(lái)編碼。
消息主體里按照字段個(gè)數(shù)又分為多個(gè)結(jié)構(gòu)類似的部分,每部分都是以 --boundary 開始,緊接著是內(nèi)容描述信息,然后是回車,最后是字段具體內(nèi)容(文本或二進(jìn)制)。
如果傳輸?shù)氖俏募€要包含文件名和文件類型信息。
消息主體最后以 --boundary-- 標(biāo)示結(jié)束。
iOS多圖片上傳
<pre>
/**
- 上傳圖片
- @param operations 上傳圖片等預(yù)留參數(shù)---視具體情況而定 可移除
- @param imageArray 上傳的圖片數(shù)組
- @parm width 圖片要被壓縮到的寬度
- @param urlString 上傳的url---請(qǐng)?zhí)顚懲暾膗rl
- @param successBlock 上傳成功的回調(diào)
- @param failureBlock 上傳失敗的回調(diào)
- @param progress 上傳進(jìn)度
*/
+(void)uploadImageWithOperations:(NSDictionary *)operations withImageArray:(NSArray *)imageArray withtargetWidth:(CGFloat )width withUrlString:(NSString *)urlString withSuccessBlock:(requestSuccess)successBlock withFailurBlock:(requestFailure)failureBlock withUpLoadProgress:(uploadProgress)progress;
{
//1.創(chuàng)建管理者對(duì)象
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager POST:urlString parameters:operations constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSUInteger i = 0 ;
/**出于性能考慮,將上傳圖片進(jìn)行壓縮*/
for (UIImage * image in imageArray) {
//image的分類方法
UIImage * resizedImage = [UIImage IMGCompressed:image targetWidth:width];
NSData * imgData = UIImageJPEGRepresentation(resizedImage, .5);
//拼接data
[formData appendPartWithFileData:imgData name:[NSString stringWithFormat:@"picflie%ld",(long)i] fileName:@"image.png" mimeType:@" image/jpeg"];
i++;
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
progress(uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary * _Nullable responseObject) {
successBlock(responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failureBlock(error);
}];
}
</pre>
擴(kuò)展
四種常見的 POST 提交數(shù)據(jù)方式:以上兩種 + application/json + text/xml
參考
1.http://stackoverflow.com/questions/4007969/application-x-www-form-urlencoded-or-multipart-form-data
2.https://imququ.com/post/four-ways-to-post-data-in-http.html#toc-2