向本地的apache服务器上传文件
2016-05-03 21:29
691 查看
上传文件
上传单个文件
通过火狐浏览器中的Firebug插件,可以查看浏览器发送的数据包内容//上传单个文件的数据包内容解析: // 请求头 Content-Type multipart/form-data; boundary=itheima //-boundary分隔符,可以是任意字符和数字的组合,但是不能包含中文. // 请求体(就是向服务器发送的数据,类型为NSData) --itheima //根据上面请求头中的boundary设置的边界标识来分隔开请求体 Content-Disposition: form-data; name="userfile"; filename="abc.txt" Content-Type: text/plain 11111111111111 1111111111111 111111111111 1111111111 --itheima-- //name:服务器接收文件数据对应的字段名 //filename:上传数据保存到服务器使用的文件名 //Content-Type: text/plain表示上传文件是文本数据 *********************下面是更为具体的解释********************* name:服务器上传文件的字段名称,可以找公司后台要 filename:保存到服务器上的文件名,通常不允许重复,但是后端脚本会处理。 Content-Type:告诉服务器当前文件的类型(MIMEType),一般划分格式为: 大类型/小类型 text/plain 纯文本 text/html html文件 text/xml xml文件 image/png image/gif image/jpg application/json application/octet-stream 任意的二进制数据 ........ 如果不知道填什么,百度下就行了,没必要死记。
具体实现代码
#import "ViewController.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 读取文件数据 NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"abc.txt" ofType:nil]]; // 上传文件 [self uploadFile:data fieldName:@"userfile" fileName:@"bbb.txt"]; } #define HMBoundary @"itheima" - (void)uploadFile:(NSData *)fileData fieldName:(NSString *)fieldName fileName:(NSString *)fileName{ // 负责处理上传文件的PHP脚本文件的URL(要先将该脚本文件放到apache服务器中) NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload.php"]; // 可变的Request,因为需要修改默认的参数,如请求方法,请求头等内容 NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 设置请求方法 request.HTTPMethod = @"POST"; // 设置请求头:告诉服务器客户端是做文件上传操作 [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",HMBoundary] forHTTPHeaderField:@"Content-Type"]; // 设置请求体 request.HTTPBody = [self fileData:fileData fieldName:fieldName fileName:fileName]; // 发送请求,上传文件 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //读取从服务器返回的JSON数据 NSLog(@"%@--%@",response,[NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]); }]; } /** * 拼接请求体内容 * * @param fileData 要上传文件的二进制数据 * @param fieldName 服务器接收文件数据的使用的字段名(找服务器开发人员要) * @param fileName 保存服务器使用的文件名 */ /* --itheima \r\n Content-Disposition: form-data; name="userfile"; filename="abc.txt" \r\n Content-Type: application/octet-stream \r\n\r\n 上传文件的二进制数据 \r\n--itheima-- */ - (NSData *)fileData:(NSData *)fileData fieldName:(NSString *)fieldName fileName:(NSString *)fileName{ NSMutableData *dataM = [NSMutableData data]; // 创建可变字符串用来评价请求体内容 // 换行符是\r\n NSMutableString *strM = [NSMutableString stringWithFormat:@"--%@\r\n",HMBoundary]; [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\" \r\n",fieldName,fileName]; [strM appendString:@"Content-Type: application/octet-stream \r\n\r\n"]; // 将上面的字符串以UTF-8编码后拼接到dataM中(字符串类型转NSdata类型) [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]]; // 拼接文件的二进制数据 [dataM appendData:fileData]; // 结尾标记 NSString *tail = [NSString stringWithFormat:@"\r\n--%@--",HMBoundary]; // 将结尾标记字符串拼接到dataM后面 [dataM appendData:[tail dataUsingEncoding:NSUTF8StringEncoding]]; return dataM; } @end
上传多个文件
用PHP脚本上传两个文件,查看发送的数据格式通过火狐浏览器中的Firebug插件,可以查看浏览器发送的数据包内容
//上传单个文件的数据包内容解析: // 请求头 Content-Type multipart/form-data; boundary=itheima //-boundary分隔符,可以是任意字符和数字的组合,但是不能包含中文 //上传两个文件的请求体,多个文件以此类推 --itheima\r\n Content-Disposition: form-data; name="userfile[]"; filename="xxxx.txt"\r\n Content-Type: text/plain\r\n\r\n //上传文件1的二进制数据\r\n 11111111111111 1111111111111 111111111111 1111111111 --itheima\r\n Content-Disposition: form-data; name="userfile[]"; filename="abc.txt"\r\n Content-Type: text/plain\r\n\r\n //上传文件2的二进制数据\r\n 222222222 222222222 222222222 22222222 2222 --itheima\r\n Content-Disposition: form-data; name="username"\r\n\r\n //用户名\r\n rose --itheima--
具体代码实现
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 加载文件数据 NSData *fileData1 = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"abc.txt" ofType:nil]]; NSData *fileData2 = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"aaaa.png" ofType:nil]]; // 如何传递参数? // 创建一个保存文件数据的字典 NSDictionary *fileDict = [NSDictionary dictionaryWithObjectsAndKeys:fileData1,@"ccc.txt",fileData2,@"ooo.png",nil]; // 创建一个保存用户名和密码的字典 NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:@"jack",@"username",@"123456",@"password",nil]; // 上传文件 [self uploadFile:fileDict params:params fieldName:@"userfile[]"]; } #define HMBoundary @"itheima" - (void)uploadFile:(NSDictionary *)fileDict params:(NSDictionary *)params fieldName:(NSString *)fieldName{ // URL NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload-m.php"]; // Request NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 设置请求方法 request.HTTPMethod = @"POST"; // 设置请求头:告诉服务器客户端是做文件上传 [request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@",HMBoundary] forHTTPHeaderField:@"Content-Type"]; // 设置请求体 request.HTTPBody = [self fileData:fileDict params:params fieldName:fieldName]; // 发送请求,上传文件 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { NSLog(@"%@--%@",response,[NSJSONSerialization JSONObjectWithData:data options:0 error:NULL]); }]; } /** * 拼接请求体内容 * * @param fileData 要上传文件的二进制数据 * @param fieldName 服务器接收文件数据的使用的字段名(找服务器开发人员要) * @param fileName 保存服务器使用的文件名 */ - (NSData *)fileData:(NSDictionary *)fileDict params:(NSDictionary *)params fieldName:(NSString *)fieldName{ NSMutableData *dataM = [NSMutableData data]; // 遍历文件字典 // key:保存到服务器的文件名 [fileDict enumerateKeysAndObjectsUsingBlock:^(id fileName, id fileData, BOOL * _Nonnull stop) { // 创建可变字符串用来评价请求体内容 NSMutableString *strM = [NSMutableString stringWithFormat:@"--%@\r\n",HMBoundary]; [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\" \r\n",fieldName,fileName]; [strM appendString:@"Content-Type: application/octet-stream \r\n\r\n"]; // 将上面的字符串以UTF-8编码后拼接到dataM中(字符串类型转NSdata类型) [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]]; // 拼接文件的二进制数据 [dataM appendData:fileData]; // 将结尾标记字符串拼接到dataM后面 [dataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]]; }]; // 遍历普通参数字典 // key: 对应服务器接收数据的字段名 [params enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { // 创建可变字符串用来评价请求体内容 NSMutableString *strM = [NSMutableString stringWithFormat:@"--%@\r\n",HMBoundary]; [strM appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key]; [strM appendFormat:@"%@\r\n",obj]; [dataM appendData:[strM dataUsingEncoding:NSUTF8StringEncoding]]; }]; // 结尾标记 NSString *tail = [NSString stringWithFormat:@"--%@--",HMBoundary]; // 将结尾标记字符串拼接到dataM后面 [dataM appendData:[tail dataUsingEncoding:NSUTF8StringEncoding]]; return dataM; }
相关文章推荐
- Apache Spark在SnappyData支持即时SQL分析
- apache commons io 生成报告(2016-04-21更新)
- apache commons io 持续集成(2016-04-21更新)
- Apache Commons Codec 编码解码
- Linux下apache+php+mysql搭建配置记录
- linux下apache+php搭建配置记录
- Apache 防盗链配置详解介绍
- apache主要配置详解
- 不同php版本中VC6与VC9,Thread Safety与None-Thread Safe,Apache module与fastcgi的区别与选择
- wamp添加最新版本php7和apache
- PHP7+Apache2.4+Mysql安装配置(win7环境下)
- 编译安装Apache+PHP
- Apache windows多线程设置
- Linux安装单节点Apache Hadoop示例
- ApacheActiveMQ安装必要条件
- 部署django+apache wsgi
- org.apache.catalina.startup.Catalina start之过程分析
- .htaccess简单的语法规则和flags
- Apache Maven项目提供的JAR插件详解
- Windows无法访问VMWare虚拟机下CentOS的apache服务器