AFNetworking3.1.0源码分析(七)详解AFHTTPRequestSerializer 之AFStreamingMultipartFormData上
来源:互联网 发布:php搭建app服务器 编辑:程序博客网 时间:2024/05/18 15:30
本文主要介绍关于AFNetworking中对文件上传的处理,涉及到的知识点:
1:PUT 和 POST 方式的区别
2:http MIMEType multipart/form-data
3:如何手动实现文件上传功能(使用iOS NSMutableRequest,NSURLConnection或者NSURLSession)的请求对象创建和配置
4:AFNetWorking 的封装实现提交诸如:文本、图片等数据到服务器即文件的上传功能的请求对象创建和配置
针对以上问题下面做详细的介绍:
1:PUT 和 POST 方式都可以用来向服务器提交数据,不同的是如果有多个请求发送,PUT会覆盖掉前面的所有请求执行的操作,而POST请求会执行多个不同的请求操作
2:multipart/form-data 是一种多用途formdata,普通的form表单提交数据不能提交文件类型的数据,所以multipart/form-data是一种对普通form表单提交数据的一种扩充,建立在普通的post请求至上的一种请求操作
3:如果手动实现文件的上传比如向服务器上传多张图片(本例子以上传两张png图片 :1.png,2.png)生成的请求体格式如下:
--tsunamierImageFlagContent-Disposition: form-data; name="0"; filename=1.pngContent-Type: image/png图片二进制数据--tsunamierImageFlagContent-Disposition: form-data; name="1"; filename=2.pngContent-Type: image/png图片二进制数据--tsunamierImageFlag--
以上格式需要转换成data详细步骤如下:
①:创建NSMutableRequest 对象:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:];
②:设置request请求头
NSString *BOUNDARY = @"tsunamierFileFlag";//此处的标识符对应着请求体中的标识NSString *ContentType=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",BOUNDARY];[request setValue:ContentType forHTTPHeaderField:@"Content-Type"]③:设置request请求体data数据:
NSArray *images = @[[UIImage imageNamed:@"1.png"],[UIImage imageNamed:@"2.png"]]; NSArray *imageNames = @[@"1.png",@"2.png"]; NSString *BOUNDARY = @"tsunamierImageFlag"; //分界符号 --tsunamierFileFlag NSString *BoundarySingle=[[NSString alloc]initWithFormat:@"--%@",BOUNDARY]; //结束符 --tsunamierFileFlag-- NSString *endBoundary=[[NSString alloc]initWithFormat:@"%@--",BoundarySingle]; NSMutableData *data = [[NSMutableData alloc] init]; NSMutableString *str = [[NSMutableString alloc] init]; for (int i = 0; i < [images count]; i++) { [str appendFormat:@"%@\r\n",BoundarySingle]; [str appendFormat:@"Content-Disposition: form-data; name=\"%d\"; filename=%@\r\n",i,[imageNames objectAtIndex:i]]; [str appendFormat:@"Content-Type: image/png\r\n\r\n"]; [data appendData:[str dataUsingEncoding:NSUTF8StringEncoding]]; NSData *imageData =UIImagePNGRepresentation([images objectAtIndex:i]); [data appendData:imageData]; [data appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; } NSString *end=[[NSString alloc]initWithFormat:@"%@%@",str,endBoundary]; [data appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
4:详细介绍AFNetWorking实现设置request:
4.1首先看下相关的类:
AFNEtworking 的使用例子:
NSString *filePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"logo" ofType:@"png"]; UIImage *image = [UIImage imageWithContentsOfFile:filePath]; NSData *data = UIImagePNGRepresentation(image); [self.manager POST:@"post" parameters:@{@"key":data} constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) { [formData appendPartWithFileData:[@"Data" dataUsingEncoding:NSUTF8StringEncoding] name:@"DataName" fileName:@"DataFileName" mimeType:@"data"]; } progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) { XCTAssertTrue([responseObject[@"files"][@"DataName"] isEqualToString:@"Data"]); XCTAssertTrue([responseObject[@"form"][@"key"] isEqual:data]); [expectation fulfill]; } failure:nil];使用Charles(破解版)监听请求之后的数据(在单元测试中将url scheme 改成http):
POST /post HTTP/1.1Host: httpbin.orgContent-Type: multipart/form-data; boundary=Boundary+71B60CED9389BE5CConnection: keep-aliveAccept: */*User-Agent: (null)/(null) (iPhone; iOS 10.1; Scale/2.00) yiAccept-Language: en;q=1Content-Length: 21599Accept-Encoding: gzip, deflate--Boundary+71B60CED9389BE5CContent-Disposition: form-data; name="key"图片二进制数据--Boundary+71B60CED9389BE5CContent-Disposition: form-data; name="DataName"; filename="DataFileName"Content-Type: dataData--Boundary+71B60CED9389BE5C--
可以看到在请求头结束之后的空两行就是请求体,使用分隔符隔离,此分隔符在 Content-Type字段已经给出,后端接受到数据之后根据此分隔符解析数据,因此所说multipart/form-data提供了能在请求体中使用多种类型的数据进行复合类型的请求,使用自定义分隔符标识每段请求内容,每个请求内容段都可以设置自己的:
Content-Type,Content-Disposition
- AFNetworking3.1.0源码分析(七)详解AFHTTPRequestSerializer 之AFStreamingMultipartFormData上
- AFNetworking3.1.0源码分析(八)AFHTTPRequestSerializer 之AFStreamingMultipartFormData下
- AFNetworking3.1.0源码分析(三)AFHTTPRequestSerializer 之AFQueryStringPair
- AFNetworking3.1.0源码分析(四)详解AFHTTPRequestSerializer 之初始化方法
- AFNetworking3.1.0源码分析(五)详解AFHTTPRequestSerializer 之创建NSMutableURLRequest
- AFNetworking3.1.0源码分析(六)详解AFHTTPRequestSerializer 之序列化NSMutableURLRequest
- AFNetworking3.1.0源码分析(九)AFHTTPRequestSerializer 之解决调用Amazon S3 服务出现的bug
- AFNetworking3.1.0源码分析(十)之AFSecurityPolicy
- AFNetworking3.1.0源码分析(十一)之AFSecurityPolicy验证服务器信任
- AFNetworking3.1.0源码分析(一)整体框架和功能模块
- AFNetworking3.1.0源码分析(十二)AFURLResponseSerialization
- AFNetworking3.1.0源码分析(十四)AFHTTPSessionManager
- AFNetworking3.1.0源码分析(十三)AFURLSessionManager
- kubenetes源码分析之DNS(七)
- AFNetworking3.0源码解读(一)之 AFNetworkReachabilityManager
- iOS 之 AFNetWorking3.1.0
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(七):Docker Container网络 (上)
- 平台大小端 , 结构体大小-面试题
- IE的layout属性详解
- 最好的8个 Java RESTful 框架
- PL/SQL工具报:无效的窗口句柄
- IO流学习总结
- AFNetworking3.1.0源码分析(七)详解AFHTTPRequestSerializer 之AFStreamingMultipartFormData上
- MySQL 使用可视化工具导出与导入数据
- SequoiaDB版本在线升级介绍说明
- iOS 内存管理
- 交叉编译boost库
- R quantmod chart indicator
- AOJ47字符串匹配
- 《html5超长篇学习笔记》
- JQurey input输入框聚焦变色