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

来源:互联网 发布:node nexttick 编辑:程序博客网 时间:2024/06/01 22:54

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


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


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-Typemultipart/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>
控制台结果输出如下:



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


0 0