POST 上传数据
在开发中我们很多情况下需要用到上传数据,比如传用户的基本信息 姓名、性别、账户名、密码这类的我们拼接某种格式的字符串,还有上传多张图片、本地文件.
这样根据需要选择不同的表单form格式. 今天说一下最近用到的 本地多文件压缩上传
主要借鉴了 大大 a15950711997的博客 点击打开链接
POST 的 各种设置
1.创建POST请求
NSURL* url = [NSURL URLWithString:[[netUrl stringByAppendingString: @"/api/data/AddRemote_Data"]stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL: url];
2.设置请求的form格式
这里要注意HTTP设置. 例如Content-Type 设置Content-Type是告诉服务器你上传的数据格式,如果不设置默认是application/x-www-form-urlencoded 其他还有multipart/form-data , application/json , text/xml 等等.
NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
//设置HTTPHeader
[request setValue:content forHTTPHeaderField:@"Content-Type"];
上传数据要告诉服务器你是如何分割数据的内容,不然服务器无法判断上传数据的有效性.一般多数第三方都会把这个做好, 这里看一下实现.创建一个分界符将不同的数据隔开,服务器就能根据分界符分割数据
//分界线 --AaB03x
NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
//结束符 AaB03x--
NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
这里表单中得很多数据拼接在一起都需要分界符把他们隔开
+ (NSMutableString*)setParamsKey:(NSString*)key value:(NSString*)value body:(NSMutableString*)body{
NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
//分界线 --AaB03x
NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
//添加分界线,换行
[body appendFormat:@"%@\r\n",MPboundary];
//添加字段名称,换2行
[body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
//添加字段的值
[body appendFormat:@"%@\r\n",value];
return body;
}
上传数据最好加一个数据的长度校验,避免数据漏传
//设置Content-Length
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[myRequestData length]] forHTTPHeaderField:@"Content-Length"];
还有要确定服务器有没有做Authorization认证 如果做了! 客户端HTTP一定要加上Authorization认证 否则就传不上去
NSString *token = [NSString stringWithFormat:@"Bearer %@",[BSUserSGton userHandle].user_token];
[request setValue: token forHTTPHeaderField:@"Authorization"];
如果HTTP做了以上设置之后 就可以把拼接的data 设置成httpbody 上传到服务器
//设置http body
[request setHTTPBody:myRequestData];
//http method
[request setHTTPMethod:@"POST"];
HTTP 还有很多其他基础设置有些是默认的就没加,如果具体的应用需要设置请加上。可以谷歌或者百度看一下HTTP的基本字段设置
贴一下完整的调用方法
+(void)ChangePwdWithnetUrl:(NSString*)netUrl upLoadWay:(NSString *)uploadWay userID:(NSString*)userID deviceID:(NSString *)deviceID filenames:(NSArray *)filenames data:(NSData *)fileData method: (RequestType)method finish: (Finish)finish error: (Error)error{
NSURL* url = [NSURL URLWithString:[[netUrl stringByAppendingString: @"/api/data/AddRemote_Data"]stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL: url];
//分界线 --AaB03x
NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
//结束符 AaB03x--
NSString *endMPboundary=[[NSString alloc]initWithFormat:@"%@--",MPboundary];
if (method == POST)
{
// 获取数组里面的所有文件 写进data
//
// NSString *path = [[NSBundle mainBundle] pathForResource:@"20160510103203.zip" ofType:nil];
NSMutableArray *arr = [NSMutableArray array];
// NSURL *url2 = [NSURL fileURLWithPath:path];
// NSData *filedata = [NSData dataWithContentsOfURL:url2];
// FMDB 是根据路径操作的 所以先找到路径
NSString *nameList = [NSString stringWithFormat:@"ECGDatalist.db"];
NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).firstObject stringByAppendingPathComponent:nameList];
// 根据路径去创建一个数据库
FMDatabase *db = [FMDatabase databaseWithPath:path];
if ([db open]) {
NSLog(@"数据库打开成功");
}else
{
NSLog(@"数据库打开失败");
}
for (int i = 0; i < filenames.count; i ++) {
// 根据fileName 找到数据库里面表的信息
NSString *BeginDT = @"";
NSString *EndDT = @"";
NSString *fileName = filenames[i] ;
if (fileName.length > 12) {
fileName = [ fileName substringToIndex:12];
}
FMResultSet *rs = [db executeQuery:@"SELECT * FROM APPInformationlist where FileName = ?",fileName];
while ([rs next]) {
BeginDT = [rs stringForColumn:@"BeginDT"];
EndDT = [rs stringForColumn:@"EndDT"];
}
if (EndDT == nil || [EndDT isEqualToString:@""]) {
EndDT = BeginDT;
}
NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
dic[@"UserID"] = userID;
dic[@"DeviceID"] = deviceID;
dic[@"BeginDT"] = BeginDT;
dic[@"EndDT"] = EndDT;
dic[@"FileName"] = filenames[i];
NSDictionary *dict = [NSDictionary dictionaryWithDictionary:dic];
[arr addObject:dict];
}
NSMutableArray *strArray = [NSMutableArray array];
for (int i = 0; i < arr.count; i++) {
NSString *str = [self dictionaryToJson:arr[i]];
[strArray addObject:str];
}
NSString* parString = [strArray componentsJoinedByString: @","];
NSString *listString = [NSString stringWithFormat:@"[%@]",parString];
NSMutableString *mutableString = [[NSMutableString alloc]init];
// 第一个参数 userID
mutableString = [self setParamsKey:@"userID" value:userID body:mutableString];
// 第二个参数
mutableString = [self setParamsKey:@"desDataJson" value:listString body:mutableString];
// 第三个参数
mutableString = [self setParamsKey:@"upLoadWay" value:uploadWay body:mutableString];
#pragma mark 添加文件流
// 添加分界线,换行
[mutableString appendFormat:@"%@\r\n",MPboundary];
//声明文件字段,文件名
[mutableString appendFormat:@"Content-Disposition: form-data; name=\"upfile\"; filename=\"%@\"\r\n",@"20160510103203.zip"];
//声明上传文件的格式
[mutableString appendFormat:@"Content-Type: %@\r\n\r\n",@"application/octet-stream"];
//声明结束符:--AaB03x--
NSString *end=[[NSString alloc]initWithFormat:@"\r\n%@",endMPboundary];
//声明myRequestData,用来放入http body
NSMutableData *myRequestData=[NSMutableData data];
//将body字符串转化为UTF8格式的二进制
[myRequestData appendData:[mutableString dataUsingEncoding:NSUTF8StringEncoding]];
//将file的data加入
[myRequestData appendData:fileData];
//加入结束符--AaB03x--
[myRequestData appendData:[end dataUsingEncoding:NSUTF8StringEncoding]];
#pragma mark 至此 上传的data 完毕
//设置HTTPHeader中Content-Type的值
NSString *content=[[NSString alloc]initWithFormat:@"multipart/form-data; boundary=%@",TWITTERFON_FORM_BOUNDARY];
//设置HTTPHeader
[request setValue:content forHTTPHeaderField:@"Content-Type"];
//设置Content-Length
[request setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[myRequestData length]] forHTTPHeaderField:@"Content-Length"];
//设置http body
[request setHTTPBody:myRequestData];
//http method
[request setHTTPMethod:@"POST"];
}
NSString *token = [NSString stringWithFormat:@"Bearer %@",[BSUserSGton userHandle].user_token];
[request setValue: token forHTTPHeaderField:@"Authorization"];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue currentQueue] completionHandler:^(NSURLResponse* _Nullable response, NSData* _Nullable data, NSError* _Nullable connectionError) {
if (nil == connectionError) {// 请求成功后block调用
finish(data);
} else {// 请求失败后block调用
NSLog(@"失败");
error(connectionError);
}
}];
}
拼接data的方法
+ (NSMutableString*)setParamsKey:(NSString*)key value:(NSString*)value body:(NSMutableString*)body{
NSString *TWITTERFON_FORM_BOUNDARY = @"AaB03x";
//分界线 --AaB03x
NSString *MPboundary=[[NSString alloc]initWithFormat:@"--%@",TWITTERFON_FORM_BOUNDARY];
//添加分界线,换行
[body appendFormat:@"%@\r\n",MPboundary];
//添加字段名称,换2行
[body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n",key];
//添加字段的值
[body appendFormat:@"%@\r\n",value];
return body;
}