Multipart/form-data POST文件上传详解
2019-01-23 本文已影响6人
Rumbles
提交时会向服务器端发出这样的数据(已经去除部分不相关的头信息),数据如下:
POST /t2/upload.do HTTP/1.1
User-Agent: SOHUWapRebot
Accept-Language: zh-cn,zh;q=0.5
Accept-Charset: GBK,utf-8;q=0.7,*;q=0.7
Connection: keep-alive
Content-Length: 60408
Content-Type:multipart/form-data; boundary=ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Host: w.sohu.com
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="desc"
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
[.text/plain内容.....][......][......][......]...........................
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC
Content-Disposition: form-data;name="photo"; filename="photo.png"
Content-Type: image/png
Content-Transfer-Encoding: binary
[图片二进制数据]
--ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC--
基本结构
总的Header
<空行>
----KenApp299912318 [boundary]
Content-Disposition: form-data; name="<服务器端需要知道的名字>"; filename="<服务器端这个传上来的文件名>"
Content-Type: application/zip --根据不同的文件类型选择不同的值
<空行>
<二进制数据 body>
----KenApp299912318--
(上面那些都要转为二进制文件)最终都是二进制文件上传的
iOS 试例代码 [基础代码 可以封装 优化]
///> 创建header 以及请求头 //设置Content-Type boundary //设置Method为POST
NSString *boundary = @"ZnGpDtePMx0KrHh_G0X99Yef9r8JZsRJSXC";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"www.sohu.com"]];
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[requestsetValue:contentTypeforHTTPHeaderField:@"Content-Type"];
[requestsetHTTPMethod:@"post"];
///> 下面再来看请求体body怎么设置
NSMutableData *bodyData = [[NSMutableData alloc]init];//请求体数据
///> 1.添加text/plain内容 \n是换行 \r是回车 \r\n\r\n空了一格
NSString *bodyData1 = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"; Content-Type=%@\r\n\r\n",boundary,@"desc",@"text/plain"];
[bodyDataappendData:[bodyData1 dataUsingEncoding:NSUTF8StringEncoding]];
NSString*content1 =@"文字文字";
[bodyDataappendData:[content1 dataUsingEncoding:NSUTF8StringEncoding]];
///> 换行
[bodyDataappendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
///> 2. 添加图片二进制 如果有多个文件,就重复设置文件部分,使用不同的`name`标识。
NSString*name =@"imageName";
NSString*filename =@"imageName.png";
NSString*fileContentType =@"image/png";
NSString *bodyData2 = [NSString stringWithFormat:@"--%@\r\nContent-Disposition: form-data; name=\"%@\"; filename=\"%@\" Content-Type=%@\r\n\r\n",boundary,name,filename,fileContentType];
[bodyDataappendData:[bodyData2 dataUsingEncoding:NSUTF8StringEncoding]];
NSData*content2 = [NSDatanew];
[bodyDataappendData:content2];
///> 换行
[bodyDataappendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
//设置结尾
[bodyDataappendData:[[NSString stringWithFormat:@"--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
request.HTTPBody= bodyData;
//设置请求头总数据长度
[requestsetValue:[NSString stringWithFormat:@"%lu",(unsigned long)bodyData.length] forHTTPHeaderField:@"Content-Length"];
NSURLSessionDataTask*dataTask = [[NSURLSessionsharedSession]dataTaskWithRequest:requestcompletionHandler:^(NSData*_Nullabledata,NSURLResponse*_Nullableresponse,NSError*_Nullableerror) {
NSJSONSerialization *object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSDictionary*dict = (NSDictionary*)object;
NSLog(@"=====%@",[dict objectForKey:@"success"]);
}];
//开始任务
[dataTaskresume];