概述
Http协议对文件上传协议要求的1. 必须设置请求头Content-Type为multipart/form-data。在iOS中后面需要跟上分隔符比如:boundary=----WebKitFormBoundaryDYeXSvJz9Yuyf6Du。分割可以任意字符
2. 上传的参数是有要求的,具体的数据格式如下
如果请求头没有设置Content-Type为multipart/form-data则为普通的POST请求。
文件上传
通过NSURLConnection上传文件
#define FMDataWithString(Str) [Str dataUsingEncoding:NSUTF8StringEncoding]
#define FMNewLine FMDataWithString(@"\r\n")
// #define FMSeparator @"----WebKitFormBoundaryt8fVxWuv0hn9uOjt" 分隔符
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 设置POST请求
request.HTTPMethod = @"POST";
// 上传的请求头必须参数设置
[request setValue:@"multipart/form-data; boundary=----WebKitFormBoundaryt8fVxWuv0hn9uOjt" forHTTPHeaderField:@"Content-Type"];
// 处理请求体
request.HTTPBody = [self handleHttpBody];
// 发送请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
NSLog(@"-------------%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
}
- (NSMutableData *)handleHttpBody
{
NSData *imageData = UIImageJPEGRepresentation([UIImage imageNamed:@"Snip20180325_5"], 1.0);
NSMutableData *httpBodyData = [NSMutableData data];
[httpBodyData appendData:FMDataWithString(@"------WebKitFormBoundaryt8fVxWuv0hn9uOjt")]; [httpBodyData appendData:FMNewLine];
[httpBodyData appendData:FMDataWithString(@"Content-Disposition: form-data; name=\"file\"; filename=\"Snip20180325_11.png\"")]; [httpBodyData appendData:FMNewLine];
[httpBodyData appendData:FMDataWithString(@"Content-Type: image/png")]; [httpBodyData appendData:FMNewLine];
[httpBodyData appendData:FMNewLine];
[httpBodyData appendData:imageData]; [httpBodyData appendData:FMNewLine];
[httpBodyData appendData:FMNewLine];
// 非文件参数
[httpBodyData appendData:FMDataWithString(@"------WebKitFormBoundaryt8fVxWuv0hn9uOjt")]; [httpBodyData appendData:FMNewLine];
[httpBodyData appendData:FMDataWithString(@"Content-Disposition: form-data; name=\"username\"")]; [httpBodyData appendData:FMNewLine];
[httpBodyData appendData:FMNewLine];
[httpBodyData appendData:FMDataWithString(@"tom")]; [httpBodyData appendData:FMNewLine];
// 结束分隔符
[httpBodyData appendData:FMDataWithString(@"------WebKitFormBoundaryt8fVxWuv0hn9uOjt--")];
return httpBodyData;
}
@end
NSURLSession上传文件
使用NSURLSession上传文件跟NSURLConnection对比两者步骤差不多,只是请求体的位置不一样。NSURLConnection数据是放在request中。NSURLSession放在参数中;
NSURLSessionUploadTask *task = [[NSURLSession sharedSession] uploadTaskWithRequest:request fromData:[self handleHttpBody] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"-------------%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}];
AFNetworking文件上传
NSDictionary *param = @{@"username": @"CoderHong"};
[[AFHTTPSessionManager manager] POST:@"http://120.25.226.186:32812/upload" parameters:param constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
/**
设置需要上传的文件
@param name 服务器字段名
@param fileName 要传递的文件名
@param mimeType 文件的mimetype
*/
[formData appendPartWithFileData:UIImageJPEGRepresentation([UIImage imageNamed:@"Snip20180325_5"], 1.0) name:@"file" fileName:@"Snip20180325_5.png" mimeType:@"image/png"];
// 通过传递文件的路径
// [formData appendPartWithFileURL:[NSURL fileURLWithPath:@""] name:@"file" fileName:@"Snip20180325_5" mimeType:@"image/png" error:nil];
// [formData appendPartWithFileURL:[NSURL fileURLWithPath:@""] name:@"file" error:nil];
} progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"-----------%@", responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
}];