首先说明下form表单请求,是一种特殊的post请求,请求方式有application/x-www-form-urlencoded、multipart/form-data、application/json。其中application/json就是我们常见的post请求,使用AFN直接请求即可。

下面开始正式的内容,如何使用AFNetworking完成form表单请求

1、application/x-www-form-urlencoded

直接上代码:

+ (AFHTTPSessionManager *)getManagerWithReqType:(requestType)reqType{

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

if(reqType == REQ_Form){

[manager.requestSerializer setValue:@"application/x-www-form-urlencoded;charset=utf-8" forHTTPHeaderField:@"Content-Type"];

}else{

manager.requestSerializer = [AFJSONRequestSerializer serializer];

manager.responseSerializer = [AFJSONResponseSerializer serializer];

[manager.requestSerializer setValue:@"application/json;text/html;charset=utf-8" forHTTPHeaderField:@"Content-Type"];

}

return manager;

}

这种form表单请求方式和我们常见的post请求方式,只有这一个地方需要区别,特别注意以下两句不能出现在application/x-www-form-urlencoded请求方式中

manager.requestSerializer = [AFJSONRequestSerializer serializer];

manager.responseSerializer = [AFJSONResponseSerializer serializer];

剩下的部分和常见的post请求一致,请求时只需要调用:

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString

parameters:(nullable id)parameters

headers:(nullable NSDictionary *)headers

progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress

success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success

failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

2、multipart/form-data

目前个人在项目中遇到的情况,主要用于上传二进制文件,使用时只需要在常见post请求的基础上,设置Content-Type为:

[manager.requestSerializer setValue:@"multipart/form-data; boundary=----WebKitFormBoundaryHzyefUottpz7ltKf"forHTTPHeaderField:@"Content-Type"];

在调用方法上稍有不同,multipart/form-data调用AFN的constructingBodyWithBlock方法:

- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString

parameters:(nullable id)parameters

headers:(nullable NSDictionary *)headers

constructingBodyWithBlock:(nullable void (^)(id formData))block

progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress

success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success

failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

以上传视频为例:

+(void)uploadVideoUseAFN:(NSURL *)filePath andUrl:(NSString *)urlString{

AFHTTPSessionManager *manager = [self getManager];

/// 要上传的二进制文件

NSData *videoData = [NSData dataWithContentsOfURL:filePath];

/// 二进制文件在服务器保存的路劲

NSDateFormatter *formatter = [[NSDateFormatter alloc]init];

formatter.dateFormat =@"yyyyMMddHHmmss";

NSString *str = [formatter stringFromDate:[NSDate date]];

NSString *fileName = [NSString stringWithFormat:@"%@.mp4", str];

NSURLSessionDataTask *task = [manager POST:urlString parameters:nil headers:nil constructingBodyWithBlock:^(id _Nonnull formData) {

/// 拼接formdata

[formData appendPartWithFileData:videoData

name:@"myFile"

fileName:fileName

mimeType:@"video/mpeg"];

} progress:^(NSProgress * _Nonnull uploadProgress) {

} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

}];

[task resume];

}

疑点1、关于mimeType的设置

使用AFNetworking不需要设置额外的参数(如Content-Disposition),因为在AFNetworking完成form提交时,下面的方法会自动设置Content-Disposition为@"form-data; name=\"%@\"; filename=\"%@\"

- (void)appendPartWithFileData:(NSData *)data

name:(NSString *)name

fileName:(NSString *)fileName

mimeType:(NSString *)mimeType;

觉得不妥的也可以查看appendPartWithFileData的具体实现,会发现如下内容:

[mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"];

[mutableHeaders setValue:mimeType forKey:@"Content-Type"];

这里有一个痛点,就是关于mimeType的设置,图片和视频都很方便,可以直接设置为image/jpg、image/png、video/mpeg等(最好和后台对一下,因为有些开发会指定文件类型,设置不一致会请求失败)。

但对于文件上传,mimeType设置什么就比较懵,这里可以设置万能类型application/octet-stream,服务器会自动解析文件类型。关于如何获取文件的mimeType,可以查看

疑点2、关于使用AFNetworking提交Form表单,请求成功了,但是后台接收到的数据为空

正常情况下我们使用form提交,都会在header中设置:

[manager.requestSerializer setValue:@"multipart/form-data; boundary=----WebKitFormBoundaryHzyefUottpz7ltKf"forHTTPHeaderField:@"Content-Type"];

后台没有接收到传过去的数据就是因为设置了multipart/form-data和boundary。这里最坑的就是设置了multipart/form-data和boundary,还能请求成功,让人一度人为自己写的代码没有半点毛病。

解决办法:

+ (void)uploadImageWIthimageData:(NSData *)imageData{

NSString *requestUrl = @"";

/// 设置filename

NSDateFormatter *formatter = [[NSDateFormatter alloc]init];

formatter.dateFormat =@"yyyyMMddHHmmss";

NSString *str = [formatter stringFromDate:[NSDate date]];

NSString *fileName = [NSString stringWithFormat:@"%@.jpg", str];

/// 请求配置

AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

/// 注意:如果返回结果是json类型按如下设置,data类型manager.responseSerializer = [AFHTTPResponseSerializer serializer];

manager.responseSerializer = [AFJSONResponseSerializer serializer];

manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/html",@"image/jpeg",@"image/png",@"application/octet-stream",@"text/json",nil];

/// 设置上传参数,经过测试这个可以不用传

NSDictionary *params = @{@"file":imageData};

/// 设置header

NSDictionary *headers = @{@"Authorization":@""};

NSURLSessionDataTask *task = [manager POST:requestUrl parameters:params headers:headers constructingBodyWithBlock:^(id _Nonnull formData) {

[formData appendPartWithFileData:imageData

name:@"file"

fileName:fileName

mimeType:@"image/jpg"];

} progress:^(NSProgress * _Nonnull uploadProgress) {

} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {

} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {

}];

[task resume];

}

你也不要觉得这样就不是一个multipart/form-data类型的请求了,因为AFNetworking会自动补全这一部分

ios 优化html表单提交,iOS 使用AFNetworking的form表单请求相关推荐

  1. php阻止form提交表单提交,防止表单提交时刷新页面-阻止form表单的默认提交行为...

    最近在写 ajax 提交的时候遇到一个问题,在执行 ajax 提交之后,浏览器页面自动刷新了,主要是没有 由于form 表单的默认提交行为.一下是几种阻止 form 表单默认提交行为的方式. 1.使用 ...

  2. html表单提交按钮代码,JavaScript在form表单中使用button按钮实现submit提交方法

    submit是button的一个特例,也是button的一种,它把提交这个动作自动集成了,submit和button,二者都以按钮的形式展现,看起来都是按钮,所不同的是type属性和处发响应的事件上. ...

  3. jquery表单ajax json数据,jquery序列化form表单使用ajax提交后处理返回的json数据

    1.返回json字符串: /** 将一个字符串输出到浏览器 */ protected void writeJson(String json) { PrintWriter pw = null; try ...

  4. elementui 按钮 表单_仿ElementUI实现一个Form表单的实现代码

    使用组件就像流水线上的工人:设计组件就像设计流水线的人,设计好了给工人使用. 一. 目标 仿 ElementUI 实现一个简单的 Form 表单,主要实现以下四点: Form FormItem Inp ...

  5. java表单单击路径_Form表单中的action路径问题,form表单action路径《jsp---Servlet路劲问题》这个和上一个《jsp---Servlet》文章有关...

    Form表单中的action路径问题,form表单action路径 今天刚接触web,在用jsp和servlet做一个简单的登陆的时候在Form表单action属性和method属性的一些问题: 我遇 ...

  6. Html 中表单提交的一些知识总结——防止表单自动提交,以及submit和button提交表单的区别...

    转自:http://jackaudrey.blog.163.com/blog/static/1314217882010590041833/ 在页面中有多个input type="text&q ...

  7. 简单表单提交php教程,php教程之表单提交实例

    一个超简单的初学者用的php教程之表单提交实例有需要的朋友参考一下. 下面我们将创建一个复杂的表单,代码如下所示. 实例代码如下: 姓名: 密码: 年龄: 16">小于16 16-30 ...

  8. dwz 表单提交 html,dwz 文件上传表单提交 分析

    众所周知,因为Ajax不支持enctype="multipart/form-data".所以如果想采用无刷新的方式提交文件,Ajax是不行的.采用变通,也是最简单有效的方式是在页面 ...

  9. dwz 表单提交 html,DWZ文件上传表单提交

    文件上传表单提交 因为Ajax不支持enctype="multipart/form-data" 所以用隐藏iframe来处理无刷新表单提交. 或 服务器端响应 DWZ-v1.2版本 ...

最新文章

  1. 财务人员学python有用吗-一个来自35岁职场高管的忠告:Python为什么不得不学?...
  2. WindowsPhone7真机部署和调试程序
  3. XP中怎样让批处理文件运行后,不关闭dos窗口
  4. java robot 文档_文件配置 · simple-robot 机器人开发者使用文档 · 看云
  5. 信号 09 | 函数pause
  6. centos7/rhel7下安装redis4.0集群
  7. 美国商务部发布软件物料清单 (SBOM) 的最小元素(上)
  8. hibernate查询list结果集结果都是一样
  9. jeesite图片上传并显示
  10. 计算机关闭测试模式,win10怎么开启及关闭测试模式 win10测试模式对电脑有影响吗...
  11. 语音识别/合成开源项目
  12. 电脑开机启动密码破解(win7,改sam没用)
  13. 王森:程序设计师真情忏悔录
  14. android版本兼容API24,Android 7.0 (API 24) 适配
  15. PaMIR: Parametric Model-Conditioned Implicit Representation for Image-based Human Reconstruction
  16. Linux学习笔记:DNS
  17. 教程 | 使用小O地图制作文字标注地图
  18. 离散数学重点(第二部分)
  19. html背景图片内填充,CSS基础——使用图片填充元素背景
  20. 网络游戏外挂制作 (转贴)

热门文章

  1. 解决Windows Server2008 R2中IE开网页时弹出阻止框(Windows Server2008网页无法打开的问题)...
  2. 详解linux系列之FTP的安装及配置
  3. git remote 使用总结
  4. AcWing 795. 前缀和
  5. 基础篇:3.3.2)压铸件-材料选择
  6. 代理模式vs适配器模式vs外观模式
  7. 多校#5-1005-Instring-HDU5785-manacher+维护
  8. OpenSessionInViewFilter 的配置及作用
  9. 浏览器构造页面的原理
  10. update set操作 根据变量选择colum