(一二八)使用POST上传文件
简介
上传文件到服务器是一个比较常用的操作,最基本的方式是通过POST上传,文件以二进制形式,作为一个参数传递,但是这个POST的结构相当复杂,且必须完全符合HTTP标准。
文件上传的POST格式
该POST主要由下面几个部分构成。
请求头
1.Content-Length(请求体的二进制大小)- 注意这里的二进制大小应该根据请求体计算
2.Content-Type multipart/form-data; boundary=(分隔符)
- 注意这里的分隔符与请求体的分隔符有关,但不完全一致。
请求体
基本格式示例- 这里的分隔符就是上面的分隔符,但是前面要多加两个
'-'。
--分隔符
Content-Disposition: form-data; name="uploadFile"; filename="button.png"
Content-Type: image/png
(此处空两行)
<二进制内容>
--分隔符
Content-Disposition: form-data; name="submit"
(此处空两行)
Submit
--分隔符--
(此处空一行)- 注意到最后的分隔符后面跟了
--,这个代表结束符,并且后面要跟一个空行。
格式说明
普通参数
普通参数的构成如下:Content-Disposition: form-data; name="参数名"
(此处空两行)
参数值
--分隔符多个参数可以连续拼接。
文件参数
文件参数与普通参数类似,只是多了一行MineType的说明,该说明告诉服务器文件的类型。Content-Disposition: form-data; name="uploadFile"; filename="button.png"
Content-Type: image/png
(此处空两行)
<二进制内容>
--分隔符
将二者连起来就构成了完整的文件上传POST信息,到这里我们可以理解,该POST不仅发送了文件数据,还发送了一个参数。
- 这里的分隔符就是上面的分隔符,但是前面要多加两个
文件上传的服务器php脚本
要让post请求发挥作用,必须借助php脚本实现对post的处理,换句话说,我们的post请求应该发送给该php脚本,脚本的代码如下:(注意修改uploadPath为自己服务器想要接收文件的路径)
<?php
header("Content-type: text/html; charset=utf-8");
// 配置文件需要上传到服务器的路径,需要允许所有用户有可写权限,否则无法上传!
$uploadPath = '../uploads/'; $IOS_forKey=$_FILES["uploadFile"]; if ($IOS_forKey["error"] > 0) {
echo "传入参数错误:" . $IOS_forKey["error"] . "<br />";
} else {
echo "文件: " . $IOS_forKey["name"] . "<br />";
echo "类型: " . $IOS_forKey["type"] . "<br />";
echo "大小: " . ($IOS_forKey["size"] / 1024) . " Kb<br />";
echo "临时文件: " . $IOS_forKey["tmp_name"] . "<br />"; chmod($uploadPath . $IOS_forKey["name"], 0666);
if (file_exists($uploadPath . $IOS_forKey["name"])) {
echo $IOS_forKey["name"] . "文件已经存在!";
} else {
move_uploaded_file($IOS_forKey["tmp_name"], $uploadPath . $IOS_forKey["name"]);
echo "上传文件保存在: " . $uploadPath . $IOS_forKey["name"];
}
}
?>
通过iOS设备上传文件
想要通过iOS设备上传文件,一般的做法是根据上面的结构创建URLRequset,然后发送该request到服务器请求上面的php脚本,实现文件的上传,具体的代码如下。
为了方便插入二进制文件数据,我们直接使用data拼接,因此对于每一段字符串都需要转为data,这就是DataWithStr宏的作用。
为了适配各个系统的换行符,使用\r\n。
FileBoundary就是上文提到的分隔符。
HTTP请求头的contentLength需要待请求体拼接完毕后才能得到,因此最后才赋值。
#import "ViewController.h"
#import "UploadFile.h"
#define FileBoundary @"-----------------------------test"
#define EndLine @"-----------------------------test--\r\n"
#define NewLine @"\r\n"
#define DataWithStr(str) [str dataUsingEncoding:NSUTF8StringEncoding]
@interface ViewController ()
@end
@implementation ViewController
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self upload];
}
- (void)upload{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://127.0.0.1/lesson2/upload.php"]];
request.HTTPMethod = @"POST";
// 设置请求头
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",FileBoundary];
[request setValue:contentType forHTTPHeaderField:@"Content-Type"];
// 设置请求体
NSMutableData *body = [NSMutableData data];
[body appendData:DataWithStr(@"--")];
[body appendData:DataWithStr(FileBoundary)];
[body appendData:DataWithStr(NewLine)];
[body appendData:DataWithStr(@"Content-Disposition: form-data; name=\"uploadFile\"; filename=\"test.png\"")];
[body appendData:DataWithStr(NewLine)];
[body appendData:DataWithStr(@"Content-Type: image/png")];
[body appendData:DataWithStr(NewLine)];
[body appendData:DataWithStr(NewLine)];
UIImage *img = [UIImage imageNamed:@"test.png"];
NSData *imgData = UIImagePNGRepresentation(img);
[body appendData:imgData];
[body appendData:DataWithStr(NewLine)];
// 其他参数
[body appendData:DataWithStr(@"--")];
[body appendData:DataWithStr(FileBoundary)];
[body appendData:DataWithStr(@"Content-Disposition: form-data; name=\"param1\"")];
[body appendData:DataWithStr(NewLine)];
[body appendData:DataWithStr(NewLine)];
[body appendData:DataWithStr(@"value1")];
[body appendData:DataWithStr(NewLine)];
[body appendData:DataWithStr(@"--")];
[body appendData:DataWithStr(EndLine)];
[request setValue:[NSString stringWithFormat:@"%ld",body.length] forHTTPHeaderField:@"Content-Length"];
request.HTTPBody = body;
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
NSString *result = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@",result);
}];
}
@end
(一二八)使用POST上传文件的更多相关文章
- IE8/9 JQuery.Ajax 上传文件无效
IE8/9 JQuery.Ajax 上传文件有两个限制: 使用 JQuery.Ajax 无法上传文件(因为无法使用 FormData,FormData 是 HTML5 的一个特性,IE8/9 不支持) ...
- 三种上传文件不刷新页面的方法讨论:iframe/FormData/FileReader
发请求有两种方式,一种是用ajax,另一种是用form提交,默认的form提交如果不做处理的话,会使页面重定向.以一个简单的demo做说明: html如下所示,请求的路径action为"up ...
- asp.net mvc 上传文件
转至:http://www.cnblogs.com/fonour/p/ajaxFileUpload.html 0.下载 http://files.cnblogs.com/files/fonour/aj ...
- app端上传文件至服务器后台,web端上传文件存储到服务器
1.android前端发送服务器请求 在spring-mvc.xml 将过滤屏蔽(如果不屏蔽 ,文件流为空) <!-- <bean id="multipartResolver&q ...
- .net FTP上传文件
FTP上传文件代码实现: private void UploadFileByWebClient() { WebClient webClient = new WebClient(); webClient ...
- 通过cmd完成FTP上传文件操作
一直使用 FileZilla 这个工具进行相关的 FTP 操作,而在某一次版本升级之后,发现不太好用了,连接老是掉,再后来完全连接不上去. 改用了一段时间的 Web 版的 FTP 工具,后来那个页面也 ...
- 前端之web上传文件的方式
前端之web上传文件的方式 本节内容 web上传文件方式介绍 form上传文件 原生js实现ajax上传文件 jquery实现ajax上传文件 form+iframe构造请求上传文件 1. web上传 ...
- Django session cookie 上传文件、详解
session 在这里先说session 配置URL from django.conf.urls import patterns, include, url from django.contrib i ...
- 4 django系列之HTML通过form标签来同时提交表单内容与上传文件
preface 我们知道提交表单有2种方式,一种直接通过submit页面刷新方法来提交,另一种通过ajax异步局部刷新的方法提交,上回我们说了通过ajax来提交文件到后台,现在说说通过submit来提 ...
随机推荐
- [IOI 2011]ricehub
Description 乡间有一条笔直而长的路称为“米道”.沿着这条米道上 R 块稻田,每块稻田的坐标均为一个 1 到 L 之间(含 1 和 L)的整数.这些稻田按照坐标以不减的顺序给出,即对于 0 ...
- 注意类型转换——Effective C++
注意类型转换: C++提供了四种新式类型转换: const_cast<T>(expression); static_cast<T>(expression); dynamic_c ...
- C++Primer学习——各种运算符
前缀递增和后缀递增 class NewInt { public: NewInt():RootInt(0){}; NewInt(int IniInt):RootInt(IniInt){}; NewInt ...
- hdu 5451(矩阵 +Fibonacci )
题意:求 [(5 + 2*sqrt(6))^(1 + 2^x)] % M 基于hdu2256可以求(5 + 2*sqrt(6))^ n 但是n特别大,我们可以找矩阵的循环节 两种可能 1.mod-1 ...
- [bzoj4813][Cqoi2017]小Q的棋盘
来自FallDream的博客,未经允许,请勿转载,谢谢. 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能在有连线的格点之间移动.整个棋盘上共有V ...
- 树链剖分模板(BZOJ3083)
实现了路径修改,子树查询,及换根. 换根其实很简单,分三种情况讨论,画画图就明白了. #include <cstdio> #include <algorithm> using ...
- C++内存机制中内存溢出、内存泄露、内存越界和栈溢出的区别和联系
当我们在用C++做底层驱动的时候,经常会遇到内存不足的警告,究其原因,往往是因为内存出现溢出,泄露或者越界等原因.那么他们之间有什么联系吗? 内存溢出(out of memory) 是指程序在申请内存 ...
- Python中set的功能介绍
Set的功能介绍 1.集合的两种函数(方法) 1. 集合的内置函数 交集 格式:x.__and__(y)等同于x&y 例如:s1 = {'a',1,} s2 = {'b',1,} s3 = { ...
- Jenkins简明入门(二) -- 利用Jenkins完成Python程序的build、test、deployment
大家可能还没搞清楚,Jenkins到底能做什么? 本节内容利用Jenkins完成python程序的build.test.deployment,让大家对Jenkins能做的事情有一个直观的了解. 本节内 ...
- Linux学习之CentOS(八)----文件与目录的默认权限与隐藏权限(转)
文件与目录的默认权限与隐藏权限 一个文件有若干个属性, 包括读写运行(r, w, x)等基本权限,及是否为目录 (d) 与文件 (-) 或者是连结档 (l) 等等的属性! 要修改属性的方法在前面也约略 ...