您的位置:首页 > 其它

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

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



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

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



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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: