您的位置:首页 > 运维架构 > Apache

向本地的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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: