关于AFNetworking中header的bug问题
[摘要:AFNetworking那个正在ios开辟中便未几道了,网上一搜一大推,然则详细用法我便没有道了,偶然间我会整顿一下详细的一些用法。本日首要接头一下我正在应用傍边闭于header上里的一些bug问]
AFNetworking这个在ios开发中就不多说了,网上一搜一大推,但是具体用法我就不说了,有时间我会整理一下具体的一些用法。今天主要讨论一下我在使用当中关于header上面的一些bug问题。
首先关于一个登录保持,我和服务器人员通过具体的开发交流,决定用token作为唯一的标示,也就是当你每次登陆之后,服务器会返回给你一个token,然后我就可以保存这个token,通过设置header头部添加token换取我需要的一些数据。
说起来简单,开始做。
首先,我在一个报表功能页面需要通过token获取数据,参数没有,于是我在header头部添加token代码如下
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *token=[defaults objectForKey:@"token"];
NSLog(@"%@",token);
NSMutableDictionary *parameters=[NSMutableDictionary dictionary];
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
// [mager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//往头部添加token信息
[mager.requestSerializer setValue:token forHTTPHeaderField:@"token"];
mager.responseSerializer = [AFJSONResponseSerializer serializer];
mager.requestSerializer=[AFJSONRequestSerializer serializer];
NSLog(@"%@",mager.requestSerializer.HTTPRequestHeaders);
[mager GET:@"http://192.168.0.203:5000/report/1?m=d" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败");
}];
这里说一下下面几个设置
1。
[mager.requestSerializer setValue:@"" forHTTPHeaderField:@""];
这个方法就是忘header头里面添加key_value键值对,也就是向头部添加信息,这个可以根据服务器要求来加入header。有很多人在做http请求时(注意https和http的安全性区别),往往把请求数据时需要的唯一标示放在afn的body里面,其实这样远没有放在header里面安全。下面我来举出两个例子:
首先这个是把token放在body里面
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *token=[defaults objectForKey:@"token"];
NSMutableDictionary *parameters=[NSMutableDictionary dictionary];
//token放在parameters中
parameters[@"token"]=token;
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
mager.responseSerializer = [AFJSONResponseSerializer serializer];
mager.requestSerializer=[AFJSONRequestSerializer serializer];
[mager GET:@"http://192.168.0.203:5000/report/1?m=d" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败");
}];
这个是把token放在header里面
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *token=[defaults objectForKey:@"token"];
NSMutableDictionary *parameters=[NSMutableDictionary dictionary];
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
//token放在header里面
[mager.requestSerializer setValue:token forHTTPHeaderField:@"token"];
//打印一下header里面的信息
NSLog(@"%@",mager.requestSerializer.HTTPRequestHeaders);
mager.responseSerializer = [AFJSONResponseSerializer serializer];
mager.requestSerializer=[AFJSONRequestSerializer serializer];
[mager GET:@"http://192.168.0.203:5000/report/1?m=d" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败");
}];
下面几个代码作为了解,补充一下
//这句是告诉afn,我接受的服务器传来的是一个josn数据,然后afn会自动给我们转为字典,是不是很方便?
mager.responseSerializer = [AFJSONResponseSerializer serializer];
//申明请求的数据是json类型,这里如果进行了申明,那么我们传入的字典parameters会自动被afn转换为josn类型传给服务器
mager.requestSerializer=[AFJSONRequestSerializer serializer];
//下面这句话的意思是 告诉AFN千万别解析, 我给的是什么数据就是什么数据
mager.requestSerializer=[AFHTTPRequestSerializer serializer];
//下面这句话的意思是 告诉AFN千万别解析, 只需要给我裸数据就可以
mager.responseSerializer = [AFHTTPResponseSerializer serializer];
//这句告诉afn,如果服务器返回数据没有找到我告诉的类型,比如josn,那么就给我text活着html类型
mager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
接下来,我们用header头来包装token向服务器获取数据,代码如下
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *token=[defaults objectForKey:@"token"];
NSMutableDictionary *parameters=[NSMutableDictionary dictionary];
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
[mager.requestSerializer setValue:token forHTTPHeaderField:@"token"];
mager.responseSerializer = [AFJSONResponseSerializer serializer];
mager.requestSerializer=[AFJSONRequestSerializer serializer];
NSLog(@"%@",mager.requestSerializer.HTTPRequestHeaders);
[mager GET:@"http://192.168.0.203:5000/report/1?m=d" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败");
}];
结果,服务器接受不到header里面的token,怎么回事?于是我各种调试,最后发现了问题。原来只要隐藏mager.requestSerializer=[AFJSONRequestSerializer serializer];这句就行了,既然没有在body里面传任何参数,就先注释这句,结果ok了!那么问题解除了吗?没有!因为第二天就发现问题了!
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *token=[defaults objectForKey:@"token"];
NSMutableDictionary *parameters=[NSMutableDictionary dictionary];
parameters[@"logout"]=@"1";
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
[mager.requestSerializer setValue:token forHTTPHeaderField:@"token"];
mager.responseSerializer = [AFJSONResponseSerializer serializer];
//mager.requestSerializer=[AFJSONRequestSerializer serializer];
NSLog(@"%@",mager.requestSerializer.HTTPRequestHeaders);
[mager GET:@"http://192.168.0.203:5000/report/1?m=d" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败");
}];
这时,服务器需要一个header头的token,和一个参数logout,而我注释了mager.requestSerializer=[AFJSONRequestSerializer serializer];这句代码,服务器根本就接收到的参数不是json类型,哎呀,这可怎么办!打开这句注释把,能接受josn参数但找不到header头的token,不打开吧,找到header头重的token了但参数parameters里面的类型不对,不是josn了!那试一下自己转为json类型的字符串,不让afn转了吧!结果我就下了一个jsonkit自己转,结果还是不行,服务器接受的就不是josn数据,不是json数据,那么就不返回数据了!这下可难倒我了!设置header头和mager.requestSerializer=[AFJSONRequestSerializer serializer];这句代码冲突?不可能啊!于是我开始各种百度,论坛,博客,然而,中国的复制能力真的不得不叫一个牛,千篇一律。连字体都不带改的,找不到了没办法。于是服务器人员也帮忙找,他去一个外国博客上面,看了半天,突然告诉我,你换一下顺序试试?顺序?不可能吧,开什么玩笑。他说你试试吗?反正也没招了 ,试试就试试呗!
NSUserDefaults *defaults=[NSUserDefaults standardUserDefaults];
NSString *token=[defaults objectForKey:@"token"];
NSMutableDictionary *parameters=[NSMutableDictionary dictionary];
parameters[@"logout"]=@"1";
AFHTTPRequestOperationManager*mager=[AFHTTPRequestOperationManager manager];
//先写着两行
mager.responseSerializer = [AFJSONResponseSerializer serializer];
mager.requestSerializer=[AFJSONRequestSerializer serializer];
//在设置header头
[mager.requestSerializer setValue:token forHTTPHeaderField:@"token"];
//打印一下header信息
NSLog(@"%@",mager.requestSerializer.HTTPRequestHeaders);
[mager GET:@"http://192.168.0.203:5000/report/1?m=d" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"%@",responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"请求失败");
}];
结果,运行!ok!没问题了,josn照常接受,header头也照常接收。此时,心中一万只“草泥马”奔过,这是在逗我么!于是我又换换顺序试了几遍,嗯!确实应该先把 mager.responseSerializer = [AFJSONResponseSerializer serializer] ; mager.requestSerializer=[AFJSONRequestSerializer serializer];这两行代码写在设置header头前面就可以了!哎!问题终于解决了,在这里我把那个外国博客网站发一下,里面一大堆英文,我水平不好,真看不懂!
https://www.parse.com/questions/using-afnetworking-with-parse-rest-api-for-post
好了,记录完这个bug,终于可以好好写会代码了!