文件上传步骤
1、确定文件上传路径
2、创建可变的请求对象
3、修改请求的方式为POST
+ 需要设置请求头信息 告诉服务器这是一个文件上传请求
4、设置请求体信息 (文件参数)
5、创建会话对象
6、根据会话对象创建uploadTask
7、执行tast 上传文件
特殊之处
(1) 设置请求头信息
Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryKdulihuifeng123
(2) 按照固定格式拼接数据 (文件参数的拼接格式)
------WebKitFormBoundaryKdulihuifeng123
Content-Disposition: form-data; name="file"; filename="123.png"
Content-Type: image/png
------WebKitFormBoundaryKdulihuifeng123
Content-Disposition: form-data; name="username"
abc123
------WebKitFormBoundaryKdulihuifeng123--
简化
分隔符:----WebKitFormBoundaryKdulihuifeng123
文件参数
--分隔符
Content-Disposition:参数
Content-Type:参数
空行
文件数据
非文件参数
--分隔符
Content-Disposition:参数
空行
abc123 (非文件的二进制数据)
结尾标识
--分隔符--
代码
1.NSURLSessionUploadTask-block 上传文件
#define Kboundary @"----WebKitFormBoundaryKdulihuifeng123"
#define KNewLine [@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
//1、确定文件上传路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
//2、创建可变的请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3、修改请求的方式为POST
request.HTTPMethod = @"POST";
//+ 需要设置请求头信息 告诉服务器这是一个文件上传请求
NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:header forHTTPHeaderField:@"Content-Type"];
//4、设置请求体信息 (文件参数)
//5、创建会话对象
NSURLSession *session = [NSURLSession sharedSession];
//6、根据会话对象创建uploadTask
// session上传不需要设置请求体,如果数据在request中会被忽略。
/* 参数说明
* 第一个参数 请求对象
* 第二个参数 本应该放在请求体中的信息
*/
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
//7、执行tast 上传文件
[uploadTask resume];
}
-(NSData *)getBodyData
{
//4.设置请求体
NSMutableData *data = [NSMutableData data];
//4.1 文件参数
/*
--分隔符
Content-Disposition: form-data; name="file"; filename="123.png"
Content-Type: image/png
空行
文件数据
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
//name:file 服务器规定的 file不能变固定的
//filename="123.png" 该文件上传到服务器之后的名称 可以按自己的需求来写 没什么限制
[data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
//要上传的文件的二进制数据类型 MIMEType 组成:大类型/小类型 image是大类型 png是小类型
[data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
[data appendData:KNewLine];
UIImage *image = [UIImage imageNamed:@"123"];
NSData *imageData = UIImagePNGRepresentation(image);
[data appendData:imageData];
[data appendData:KNewLine];
//4.2 非文件参数
/*
--分隔符
Content-Disposition: form-data; name="username"
空行
abc123
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
[data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
[data appendData:KNewLine];
[data appendData:[@"abc123" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
//4.3 结尾标识
/*
--分隔符--
*/
[data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
return data;
}
2.NSURLSessionUploadTask-代理方式 上传文件 (可以监听进度)
- (void)uploadDelegate{
//1、确定文件上传路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/upload"];
//2、创建可变的请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//3、修改请求的方式为POST
request.HTTPMethod = @"POST";
//+ 需要设置请求头信息 告诉服务器这是一个文件上传请求
NSString *header = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",Kboundary];
[request setValue:header forHTTPHeaderField:@"Content-Type"];
//4、设置请求体信息 (文件参数)
//5、创建会话对象
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
//6、根据会话对象创建uploadTask
// session上传不需要设置请求体,如果数据在request中会被忽略。
/* 参数说明
* 第一个参数 请求对象
* 第二个参数 本应该放在请求体中的信息
*/
NSURLSessionUploadTask *uploadTask = [session uploadTaskWithRequest:request fromData:[self getBodyData] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"%@",[[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
}];
//7、执行tast 上传文件
[uploadTask resume];
}
-(NSData *)getBodyData
{
//4.设置请求体
NSMutableData *data = [NSMutableData data];
//4.1 文件参数
/*
--分隔符
Content-Disposition: form-data; name="file"; filename="123.png"
Content-Type: image/png
空行
文件数据
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
//name:file 服务器规定的 file不能变固定的
//filename="123.png" 该文件上传到服务器之后的名称 可以按自己的需求来写 没什么限制
[data appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"123.png\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
//要上传的文件的二进制数据类型 MIMEType 组成:大类型/小类型 image是大类型 png是小类型
[data appendData:[@"Content-Type: image/png" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
[data appendData:KNewLine];
// UIImage *image = [UIImage imageNamed:@"123"];
// NSData *imageData = UIImagePNGRepresentation(image);
NSData *imageData = [NSData dataWithContentsOfFile:@"/Users/a58/Desktop/123.png"];
[data appendData:imageData];
[data appendData:KNewLine];
//4.2 非文件参数
/*
--分隔符
Content-Disposition: form-data; name="username"
空行
abc123
*/
[data appendData:[[NSString stringWithFormat:@"--%@",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
[data appendData:[@"Content-Disposition: form-data; name=\"username\"" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
[data appendData:KNewLine];
[data appendData:[@"abc123" dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
//4.3 结尾标识
/*
--分隔符--
*/
[data appendData:[[NSString stringWithFormat:@"--%@--",Kboundary] dataUsingEncoding:NSUTF8StringEncoding]];
[data appendData:KNewLine];
return data;
}
#pragma mark NSURLSessionDataDelegate
//bytesSent 本次上传的文件数据大小
//totalBytesSent 已经上传的文件数据大小
//totalBytesExpectedToSend 文件的总大小
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didSendBodyData:(int64_t)bytesSent
totalBytesSent:(int64_t)totalBytesSent
totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend{
NSLog(@"上传进度-- %f",1.0 * totalBytesSent / totalBytesExpectedToSend);
}
监听进度log
2018-04-04 16:18:30.125851+0800 NSURLSession文件上传[1870:155810] 上传进度-- 0.635642
2018-04-04 16:18:30.126051+0800 NSURLSession文件上传[1870:155810] 上传进度-- 1.000000
2018-04-04 16:18:30.339630+0800 NSURLSession文件上传[1870:155810] {"success":"上传成功"}