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];
上一篇下一篇

猜你喜欢

热点阅读