(一二八)使用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来提 ...
随机推荐
- Mac终端开启代理
使用shadowsocks开启代理,只支持浏览器开启代理,其他软件是不能够开启代理的,因为这个问题,自己一直无法用本地终端 git clone 一些库,网上查找方法,总结如下: 步骤一:开启shado ...
- hihoCoder 1595 : Numbers
Description You are given n constant integers c[1], c[2], ..., c[n] and an integer k. You are to ass ...
- 【BZOJ1036】【ZJOI2008】数的统计
接着找树剖的题...传送门(点我) 题意:给你一棵无根树,有三种操作:查询树上2点路径的点权和/最大点权:更改某点的点权. 解题思路:树链剖分裸题,我采用了常数较小的zkw线段树维护剖下来的树(毕竟线 ...
- hdu5586 BestCoder Round #64 (div.2)
问题描述 给n个数{A}_{1},{A}_{2}....{A}_{n}A1,A2....An,你可以选择一个区间(也可以不选),区间里每个数x变成f(x),其中f(x)=(1890x ...
- bzoj1433
1433: [ZJOI2009]假期的宿舍 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3371 Solved: 1425[Submit][Sta ...
- Python 编程规范
原文传送符:请点击
- Spring中<context:annotation-config/>
最近在研究Spring中<context:annotation-config/>配置的作用,现记录如下: <context:annotation-config/>的作用是向Sp ...
- 通过实例理解 RabbitMQ 的基本概念
先说下自己开发的实例. 最近在使用 Spring Cloud Config 做分布式配置中心(基于 SVN/Git),当所有服务启动后,SVN/Git 中的配置文件更改后,客户端服务读取的还是旧的配置 ...
- js前端模块化(一) commonjs
随着浏览器的发展,很多页面逻辑迁移到了客户端(表单验证等),JavaScript却没有为组织代码提供任何明显帮助,甚至没有类的概念,更不用说模块(module)了,JavaScript极其简单的代码组 ...
- jenkins更新后出现JNLP-connect,JNLP2-connect警告
在更新jenkins后出现提示 This Jenkins instance uses deprecated protocols: JNLP-connect,JNLP2-connect. It may ...