POST上传文件的原理剖析以及实例验证

  如果向本地服务器上传文件,首先做的第一件事就是修改本地服务器端存放上传文件夹的权限。具体操作如下:


在火狐利用本地服务器上传文件的做测试,数据分析如下:


POST上传文件要拼接的串

Content-Length(文件的大小)290

Content-Type multipart/form-data; boundary(分隔符)=(可以随便写,但是不能有中文)

\r\n--(可以随便写,但是不能有中文)\r\n

Content-Disposition: form-data; name="userfile(php脚本中用来读取文件的字段)"; filename="demo.json(要保存到服务器的文件名)"\r\n

Content-Type: application/octet-stream(上传文件的类型)\r\n\r\n

要上传的文件的二进制流

\r\n--(可以随便写,但是不能有中文)--\r\n

---------

***HTTP协议中关于POST上传文件的格式,就是这样约定的


回顾流程:

1. Firefox打开测试上传的页面

2.上传一个简单的文件

3.fixbug中粘贴了post Source原文件,并且按照格式添加响应的\r\n

4.就按照对应的格式,开始拼接字符串

响应(服务区返回的)

1状态行

HTTP/1.1(协议版本)200(状态码) OK

2xx成功

4xx客户端的错误

5xx服务器端的错误

2、响应头

Date(访问的时间): Tue,20 Jan201507:40:43 GMT

Server(服务器的类型): Apache/2.4.9 (Unix) PHP/5.5.14

X-Powered-By: PHP/5.5.14

Content-Length(返回内容的长度):34

Content-Type(内容的类型): application/json;charset=utf-8

3、实体数据(二进制)

{"userId":1,"userName":"zhangsan"}

客户端发送的请求

1.请求行

GET(HTTP方法) /login.php?username=zhangsan&password=zhang(资源路径和参数) HTTP/1.1(协议)

POST /login.php HTTP/1.1

2.请求头

Host(主机信息):127.0.0.1

User-Agent(浏览器的类型): Mozilla/5.0 (Macintosh; Intel Mac OS X10.10; rv:33.0) Gecko/20100101 Firefox/33.0

Accept(接收的数据类型): text/html,application/xhtml+xml,application/xml;q=0.9,

Accept-Language(语言): en-US,en;q=0.5

Accept-Encoding(压缩格式): gzip, deflate

Content-Length (数据体内容的长度)32

Content-Type(内容类型)

3.请求体

username=zhangsan&password=zhang


新建工程,代码如下:

<span style="font-size:18px;">//
//  ViewController.m
//  06-POST上传
//
//  Created by apple on 15/1/20.
//  Copyright (c) 2015年 apple. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    [self postUpLoad];
}

/**随便的字符串作为分隔符*/
static NSString *boundary = @"itcastupload";

- (void)postUpLoad {
    
    // 1. url
    NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/post/upload.php"];
    
    // 2. post请求
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:1 timeoutInterval:2.0f];
    // 2.1 指定post方法
    request.HTTPMethod = @"POST";
    
    // 2.2 拼接数据体
    NSMutableData *dataM = [NSMutableData data];
    
    //   1. \r\n--(可以随便写, 但是不能有中文)\r\n
    NSString *str = [NSString stringWithFormat:@"\r\n--%@\r\n", boundary];
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
    
    
    //   2. Content-Disposition: form-data; name="userfile(php脚本中用来读取文件的字段)"; filename="demo.json(要保存到服务器的文件名)"
#warning 更改之处(1.传到服务器后的文件名)
    NSString *fileName = @"Liuxun.png";  // 保存到服务器后的文件名
    
    str = [NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userfile\"; filename=\"%@\" \r\n", fileName];
    
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
    
    
    //   3. Content-Type: application/octet-stream(上传文件的类型)\r\n\r\n
    str = @"Content-Type: application/octet-stream\r\n\r\n";
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
    
    
    //   4. 要上传的文件的二进制流
    // 要上传图片的二进制
#warning 需要修改之处——需要上传的本地文件
    NSString *loaclFilePath = [[NSBundle mainBundle] pathForResource:@"0.png" ofType:nil];
    [dataM appendData:[NSData dataWithContentsOfFile:loaclFilePath]];
    
    //   5. \r\n--(可以随便写, 但是不能有中文)--\r\n
    str = [NSString stringWithFormat:@"\r\n--%@--\r\n", boundary];
    [dataM appendData:[str dataUsingEncoding:NSUTF8StringEncoding]];
    
    // 2.4 设置请求体
    request.HTTPBody = dataM;
    
    // 设置请求头
    //    Content-Length(文件的大小)	290
    //    Content-Type	multipart/form-data; boundary(分隔符)=(可以随便写, 但是不能有中文)
    
    NSString *headerStr = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
    
    [request setValue:headerStr forHTTPHeaderField:@"Content-Type"];
    
    
    // 3. 连接
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        
        // 反序列化处理
        id result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
        
        NSLog(@"result = %@", result);
    }];
}

@end</span>
控制台结果输出如下:



打开本地服务器文件夹如下:


你可能感兴趣的:(POST上传文件的原理剖析以及实例验证)