ios 优化html表单提交,iOS 使用AFNetworking的form表单请求
首先说明下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表单请求相关推荐
- php阻止form提交表单提交,防止表单提交时刷新页面-阻止form表单的默认提交行为...
最近在写 ajax 提交的时候遇到一个问题,在执行 ajax 提交之后,浏览器页面自动刷新了,主要是没有 由于form 表单的默认提交行为.一下是几种阻止 form 表单默认提交行为的方式. 1.使用 ...
- html表单提交按钮代码,JavaScript在form表单中使用button按钮实现submit提交方法
submit是button的一个特例,也是button的一种,它把提交这个动作自动集成了,submit和button,二者都以按钮的形式展现,看起来都是按钮,所不同的是type属性和处发响应的事件上. ...
- jquery表单ajax json数据,jquery序列化form表单使用ajax提交后处理返回的json数据
1.返回json字符串: /** 将一个字符串输出到浏览器 */ protected void writeJson(String json) { PrintWriter pw = null; try ...
- elementui 按钮 表单_仿ElementUI实现一个Form表单的实现代码
使用组件就像流水线上的工人:设计组件就像设计流水线的人,设计好了给工人使用. 一. 目标 仿 ElementUI 实现一个简单的 Form 表单,主要实现以下四点: Form FormItem Inp ...
- java表单单击路径_Form表单中的action路径问题,form表单action路径《jsp---Servlet路劲问题》这个和上一个《jsp---Servlet》文章有关...
Form表单中的action路径问题,form表单action路径 今天刚接触web,在用jsp和servlet做一个简单的登陆的时候在Form表单action属性和method属性的一些问题: 我遇 ...
- Html 中表单提交的一些知识总结——防止表单自动提交,以及submit和button提交表单的区别...
转自:http://jackaudrey.blog.163.com/blog/static/1314217882010590041833/ 在页面中有多个input type="text&q ...
- 简单表单提交php教程,php教程之表单提交实例
一个超简单的初学者用的php教程之表单提交实例有需要的朋友参考一下. 下面我们将创建一个复杂的表单,代码如下所示. 实例代码如下: 姓名: 密码: 年龄: 16">小于16 16-30 ...
- dwz 表单提交 html,dwz 文件上传表单提交 分析
众所周知,因为Ajax不支持enctype="multipart/form-data".所以如果想采用无刷新的方式提交文件,Ajax是不行的.采用变通,也是最简单有效的方式是在页面 ...
- dwz 表单提交 html,DWZ文件上传表单提交
文件上传表单提交 因为Ajax不支持enctype="multipart/form-data" 所以用隐藏iframe来处理无刷新表单提交. 或 服务器端响应 DWZ-v1.2版本 ...
最新文章
- 财务人员学python有用吗-一个来自35岁职场高管的忠告:Python为什么不得不学?...
- WindowsPhone7真机部署和调试程序
- XP中怎样让批处理文件运行后,不关闭dos窗口
- java robot 文档_文件配置 · simple-robot 机器人开发者使用文档 · 看云
- 信号 09 | 函数pause
- centos7/rhel7下安装redis4.0集群
- 美国商务部发布软件物料清单 (SBOM) 的最小元素(上)
- hibernate查询list结果集结果都是一样
- jeesite图片上传并显示
- 计算机关闭测试模式,win10怎么开启及关闭测试模式 win10测试模式对电脑有影响吗...
- 语音识别/合成开源项目
- 电脑开机启动密码破解(win7,改sam没用)
- 王森:程序设计师真情忏悔录
- android版本兼容API24,Android 7.0 (API 24) 适配
- PaMIR: Parametric Model-Conditioned Implicit Representation for Image-based Human Reconstruction
- Linux学习笔记:DNS
- 教程 | 使用小O地图制作文字标注地图
- 离散数学重点(第二部分)
- html背景图片内填充,CSS基础——使用图片填充元素背景
- 网络游戏外挂制作 (转贴)
热门文章
- 解决Windows Server2008 R2中IE开网页时弹出阻止框(Windows Server2008网页无法打开的问题)...
- 详解linux系列之FTP的安装及配置
- git remote 使用总结
- AcWing 795. 前缀和
- 基础篇:3.3.2)压铸件-材料选择
- 代理模式vs适配器模式vs外观模式
- 多校#5-1005-Instring-HDU5785-manacher+维护
- OpenSessionInViewFilter 的配置及作用
- 浏览器构造页面的原理
- update set操作 根据变量选择colum