POST请求上传多张图片并携带参数

在iOS中,用POST请求携带参数上传图片是非常恶心的事情,HTTPBody部分完全需要我们自己来配置,这个HTTPBody分为3个部分,头部分可以携带参数,中间部分就是我们要传输的图片文件,尾部就是结束标识了,这些设置完了还不够,你还需要配置一下HTTPHeaderField中的Content-Length以及Content-Type,恐怕一般人都会头大:).

完整的HTTPBody解密出来后是下面的格式:

--AaB03x
Content-Disposition: form-data; name="appkey" peixunduoduo
--AaB03x
Content-Disposition: form-data; name="content" 真心太好用了!
--AaB03x
Content-Disposition: form-data; name="userid" --AaB03x
Content-Disposition: form-data; name="sumscore" --AaB03x
Content-Disposition: form-data; name="courseid" --AaB03x
Content-Disposition: form-data; name="fromapp" --AaB03x
Content-Disposition: form-data; name="sign" 003a0d94aff1c7728ab21eb785fbd544
--AaB03x
Content-Disposition: form-data; name="timestamp" --AaB03x
Content-Disposition: form-data; name="image1"; filename="1.png"
Content-Type: image/png <89504e47 0d0a1a0a 0000000d 000000c9 000000b9 0082e41b c4000000 1c69444f 5d000000 5d000000 5c000030 914514f9 5d494441 547801ec 7d0b7015 55ba2eea 8ce7a8e3 191d9ff8 0221ec50 35a335b7 4a92ec47 928d2373 4818e7e8 301254d4 0113f50e 09e21c08 1ec34b04 026a8023 210e11a3 189084b9 046a02c5 4b86644c 8e922a42 098c12ca 70490e82 6e2f8178 cd78bb4b 27c7f7fb 0d924e76 26c49c01 ecfdd078 fa059f2f fe098124 c4385d62 1c5f0c75 2dde0f81 e42a8384 8db86b91 b1aea53e 4908a401 0003d4d3 12d1a949 44a83850 ba00f69b ed439299 be63b7a7 db792dd1 e7310e14 b2d7fbfb ff017ed5 ee545a48 12fc0000 4e44ae42 > --AaB03x--

本人封装好了上传图片的类,源码如下:

NETWorkPicUpload.h
//
// NETWorkPicUpload.h
// UploadPics
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import <Foundation/Foundation.h> // 创建pictures数组需要的数据
NSData * createPNGPicture(NSString *formBoundary, UIImage *image,
NSString *name, NSString *filename); @interface NETWorkPicUpload : NSObject @property (nonatomic, strong) NSString *boundary; // 分割字符串
@property (nonatomic, strong) NSDictionary *parameters; // 携带的参数
@property (nonatomic, strong) NSArray *pictures; // 封装好的图片的数据 - (void)configRequest:(NSMutableURLRequest **)request; @end
NETWorkPicUpload.m
//
// NETWorkPicUpload.m
// UploadPics
//
// Copyright (c) 2014年 Y.X. All rights reserved.
// #import "NETWorkPicUpload.h" @implementation NETWorkPicUpload #pragma mark - 创建图片POST头部信息
- (NSData *)createParametersData
{
// 生成了头部信息
NSString *start = [NSString stringWithFormat:@"--%@", _boundary];
NSMutableString *body = [[NSMutableString alloc] init];
NSArray *keys = [_parameters allKeys]; [keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
NSString *key = keys[idx]; [body appendFormat:@"\r\n%@\r\n", start];
[body appendFormat:@"Content-Disposition: form-data; name=\"%@\"\r\n\r\n", key];
[body appendFormat:@"%@",_parameters[key]];
}]; return [body dataUsingEncoding:NSUTF8StringEncoding];
} #pragma mark - 创建图片POST尾部信息
- (NSData *)createEndData
{
NSString *end = [NSString stringWithFormat:@"\r\n--%@--\r\n", _boundary];
return [end dataUsingEncoding:NSUTF8StringEncoding];
} #pragma mark - 生成POST需要的数据格式
- (NSData *)createPostData
{
if (_boundary && _parameters)
{
NSMutableData *postData = [NSMutableData data]; // 添加头
[postData appendData:[self createParametersData]]; // 添加图片
[_pictures enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSData class]])
{
[postData appendData:obj];
}
}]; // 添加尾
[postData appendData:[self createEndData]]; return postData;
}
else
{
return nil;
}
} #pragma mark - 创建PNG格式的图片
NSData * createPNGPicture(NSString *formBoundary, UIImage *image,
NSString *name, NSString *filename)
{
NSString *start = [NSString stringWithFormat:@"--%@", formBoundary]; // 添加分界线,换行
NSMutableString *subBody = [[NSMutableString alloc] init];
[subBody appendFormat:@"\r\n%@\r\n", start];
[subBody appendFormat:@"Content-Disposition: form-data; name=\"%@\"; filename=\"%@\"\r\n",
name, filename]; // 声明上传文件的格式
[subBody appendFormat:@"Content-Type: image/png\r\n\r\n"]; // 图片data
NSData *imageData = UIImagePNGRepresentation(image); // 生成图片data
NSMutableData *tmpData = [NSMutableData data];
[tmpData appendData:[subBody dataUsingEncoding:NSUTF8StringEncoding]];
[tmpData appendData:imageData]; return [NSData dataWithData:tmpData];
} - (void)configRequest:(NSMutableURLRequest **)request
{
// 获取到了POST包体
NSData *data = [self createPostData]; // 配置请求
NSMutableURLRequest *tmpRequest = *request; // 设置请求POST包体
tmpRequest.HTTPBody = data;
tmpRequest.HTTPMethod = @"POST"; // 设置HTTPHeaderField
[tmpRequest setValue:[NSString stringWithFormat:@"%lu", (unsigned long)[data length]]
forHTTPHeaderField:@"Content-Length"];
[tmpRequest setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", _boundary]
forHTTPHeaderField:@"Content-Type"];
} @end

使用情况:

上传图片的截图:

说一下几个注意的地方:

以下地方会对request进行一些修改,注意**,这个是指针的指针,你懂得:)

大体流程就是:

1. 根据参数创建POST头部信息

2. 填充中间的图片信息

3. 用标示符表示结束信息

4. 对HTTPHeaderField进行一些设置

要实现以上这些是需要你对网络知识有着充分理解的:),也许你用惯了第三方开源代码,但不理解原理,还是很难根据需求进行必要修改,这一点需要注意哦.

POST请求上传多张图片并携带参数的更多相关文章

  1. vue中el-upload上传多图片且携带参数,批量而不是一张一张的解决方案

    现在前端基本不是vue技术栈就是react技术栈. vue技术栈最常用的就是element-ui的ui框架了. 在项目中,我们经常会碰到这种需求:批量上传文件 element-ui 确实也为我们提供了 ...

  2. Okhttp3上传多张图片同时传递参数

    之前上传图片都是直接将图片转化为io流传给服务器,没有用框架传图片. 最近做项目,打算换个方法上传图片. Android发展到现在,Okhttp显得越来越重要,所以,这次我选择用Okhttp上传图片. ...

  3. 使用volley上传多张图片,一个参数对应多张图片,转载

    https://my.oschina.net/u/1177694/blog/491834 原帖地址 而如果使用volley的话,因为请求数据那些都很简便,但遇到上传文件就麻烦那可不好,同时使用多个网络 ...

  4. iOS -- 上传多张图片 后台(PHP)代码和上传一张的一样

    // 上传多张图片 - (void)send { // 设置初始记录量为0 self.count = 0; self.upcount = 0; // 设置初始值为NO self.isUploadPic ...

  5. el-upload控件一次接口请求上传多个文件

    el-upload组件默认情况下上传多少个文件就会请求多少次上传接口,如何一次上传多个文件而不必多次请求上传接口呢?直接看代码 html <el-upload :action="act ...

  6. AFN上传多张图片

    AFN上传多张图片代码: AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager]; sessionManager.r ...

  7. POST上传多张图片配合Django接受多张图片

    POST上传多张图片配合Django接受多张图片 本地:POST发送文件,使用的是files参数,将本地的图片以二进制的方式发送给服务器. 在这里 files=[("img",op ...

  8. php用jquery-ajax上传多张图片限制图片大小

    php用jquery-ajax上传多张图片限制图片大小 /** * 上传图片,默认大小限制为3M * @param String $fileInputName * @param number $siz ...

  9. 微信JSSDK上传多张图片

    之前是使用for循环实现的,但是安卓手机没有问题,苹果手机只能上传最后一张图片. 好在有高手在前面趟路,实用的循环调用.苹果是没有,安卓不清楚.以下内容转自:http://leo108.com/pid ...

随机推荐

  1. Kafka—性能逆天的存在

    0.引言 Kafka是LinkedIn开源出来的一款消息服务器,用Scala语言实现:这货的性能是百万级的QPS(估计是挂载了多块磁盘),我随便写个测试程序就是十万级. 1.Kafka基本概念 在Ka ...

  2. HttpClient和HttpGet 参数的优先级

    http://www.cnblogs.com/LBSer/p/3295584.html 一般在使用HttpClient时,我们提前设置好参数,比如超时时间(一般socket超时和连接超时) priva ...

  3. CentOS rar

    基本unrar用法: unrar x -o- -y heidian.rar /var/www/ (把heidian.rar 文件,解压到/var/www/ 目录.要注意/ 结束)

  4. nginx学习笔记(7)Nginx如何处理一个请求---转载

    如何防止处理未定义主机名的请求基于域名和IP混合的虚拟主机一个简单PHP站点配置 基于名字的虚拟主机 Nginx首先选定由哪一个虚拟主机来处理请求.让我们从一个简单的配置(其中全部3个虚拟主机都在端口 ...

  5. Behave step matcher

    behave 提供3中step匹配模式 'parse' 'cfparse' 基于parse的扩展,  支持cardinality field syntax? 're' 支持在step中定义正则表达式 ...

  6. Node.js之Express二

    好久没写了,今天看博客,觉得有必要把node.js继续写完,善始善终.原本想着把小崔课堂继续讲下去,由于其他原因也就此耽搁下来,看看以后还有没有机会吧.废话不扯,123开始. 一.Exoress之Re ...

  7. SqlDataReader的关闭问题,报错:“阅读器关闭时尝试调用 Read 无效”

    SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);//关闭SqlDataReader 会自动关闭Sqlconn ...

  8. redis使用场景之位操作(大数据处理)

    在学习redis的过程了,看到了redis还能用于大数据处理,具体场景如下: 腾讯10亿用户,要几个毫秒内查询到某个用户是否在线,你能怎么做?千万别说给每个用户建立一个key,然后挨个记(你可以算一下 ...

  9. java SE 入门之语言与环境(第一篇)

    Javase的语言与开发环境Keke2016年03月08日 Java属于-Oracle公司(甲骨文)创始人:Gosling1995年诞生1998年12月发布jdk1.22002年2月发布:jdk1.4 ...

  10. 一分钟配置jdk

    一.下载jdk 直接进入网站:https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html ...