使用post方法上传文件的两种做法
2015-12-22 10:51
246 查看
项目需要使用HTTP协议中的POST方法上传文件,稍微总结了一下,将过程贴出来,方便以后参考。有两种方法,第一是使用NSMutableURLRequest完全从零开始设置,可以加深对HTTP协议的理解;第二种是直接使用别人封装好的代码,如AFNetworking。
重点:
注意协议中需要使用回车换行(\r\n)的位置,HTTP是一个基于文本行的协议,通过回车换行来控制格式。
注意分隔符(Boundary)的设置,尤其是(--)的增加。
设置后的内容应该是下面的样子(为了看得更清楚,将回车换行用文字表示出来了):
进行网络编程的时候,可以使用Wireshark之类的抓包工具辅助调试。可以很明确的看到发送或接收的数据是否正确。
方法一,从0开始文件上传
NSURL *url = [NSURL URLWithString:@"http://yo.diveinedu.com/upload.php"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; //0. 设置分隔符 NSString *boundary = @"a1b2c3d4e5f6"; [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forHTTPHeaderField:@"Content-Type"]; NSLog(@"%@", request.allHTTPHeaderFields); NSMutableData *httpBody = [NSMutableData data]; //1. 开始的分隔符 [httpBody appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; //2. 设置内容: 标签名,文件名等 [httpBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"fileToUpload\"; filename=\"%@\"\r\n", @"mask0.png"] dataUsingEncoding:NSUTF8StringEncoding]]; NSString *path = [[NSBundle mainBundle] pathForResource:@"mask0" ofType:@"png"]; NSLog(@"%@", [self typeForPath:path]); //3. 设置内容格式 [httpBody appendData:[[NSString stringWithFormat:@"Content-Type: %@\r\n\r\n", [self typeForPath:path]] dataUsingEncoding:NSUTF8StringEncoding]]; NSString *body = [[NSString alloc] initWithData:httpBody encoding:NSUTF8StringEncoding]; NSLog(@"%@", body); //4. 添加真正的内容 NSData *data = [NSData dataWithContentsOfFile:path]; [httpBody appendData:data]; //5. 添加结束边界 [httpBody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]]; //6. 设置http body request.HTTPBody = httpBody; //7. 发送请求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", str); }];
重点:
注意协议中需要使用回车换行(\r\n)的位置,HTTP是一个基于文本行的协议,通过回车换行来控制格式。
注意分隔符(Boundary)的设置,尤其是(--)的增加。
设置后的内容应该是下面的样子(为了看得更清楚,将回车换行用文字表示出来了):
POST /upload.php HTTP/1.1\r\n Host: yo.diveinedu.com\r\n Content-Type: multipart/form-data; boundary=abcdefghigk\r\n \r\n Content-Disposition: form-data; name="fileToUpload"; filename="mask0.png"\r\n Content-Type: image/png\r\n \r\n--abcdefghigk\r\n 图片数据 \r\n--abcdefghigk--\r\n
方法二,使用AFNetworking中的方法
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; [manager POST:@"http://yo.diveinedu.com/upload.php" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) { //1. 方法一 // NSError *error; // if (![formData appendPartWithFileURL:[NSURL fileURLWithPath:path] name:@"fileToUpload" fileName:[path lastPathComponent] mimeType:@"image/png" error:&error]) { // NSLog(@"error appending part: %@", error); // } //2. 方法二 NSData *data = [NSData dataWithContentsOfFile:path]; [formData appendPartWithFileData:data name:@"fileToUpload" fileName:[path lastPathComponent] mimeType:@"image/png"]; } success:^(AFHTTPRequestOperation *operation, id responseObject) { NSData *data = (NSData *)responseObject; NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@", str); } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"%@", error); }];
进行网络编程的时候,可以使用Wireshark之类的抓包工具辅助调试。可以很明确的看到发送或接收的数据是否正确。
相关文章推荐
- 金木水火土五行查询表
- UVA 10391 STL容器的使用
- Pike的安装(Ubuntu环境)
- androidstudio的项目使用aidl
- Ugly Number whose prime factors only include 2, 3, 5. For example, 6, 8 are ugly while 14 is not
- SecureCRT连接ubuntu时,中文显示乱码的解决方法
- Ubuntu中和用户、用户组相关的操作
- 谈下C++编程题和c语言中a/3*3的意义
- Oracle JDBC通过占位符可以查询可变长字段,不可查询固定长度字段
- Mybatis3源码分析(14)-Sql解析执行-StatementHandler
- jsp中获取get请求过来的参数
- CSS 美化 input button 按钮
- fir.im Weekly - iOS/Android 应用程序架构解析
- 无条件呼叫前转接已启用
- NSValue可以将结构转化为对象,并把它存储在集合中。
- CString 字串去除非数字
- 陪你云sdk用户指南
- Android之Dialog复选对话框
- 北斗波束
- navigationController popToViewController的用法