一、HTTP的请求方法
- GET、POST、OPTIONS、HEAD、PUT、DELETE、TRACE、CONNECT、PATCH
- 最常用的是GET和POST
二、GET和POST对比
- GET:
2.1 在请求URL后面以?的形式跟上发给服务器的参数,多个参数之间用&隔开
2.2 由于浏览器和服务器对URL长度有限制,因此在URL后面附带的参数是有限制的,通常不能超过1KB - POST:
2.3 发给服务器的参数全部放在请求体中
2.4 理论上,POST传递的数据量没有限制
三、GET和POST的选择
- 如果要传递大量数据,比如文件上传,只能用
POST
请求 -
GET
的安全性比POST
要差些,如果包含机密\敏感信息,建议用POST
p如果仅仅是索取数据(数据查询),建议使用GET
p如果是增加、修改、删除数据,建议使用POST
四、iOS中Http请求的方案
苹果原生(自带)
-
NSURLConnection
:用法简单,最古老最经典最直接的一种方案【坑比较多】 -
NSURLSession
:功能比NSURLConnection更加强大,苹果目前比较推荐使用这种技术【2013推出,iOS7开始出的技术】 -
CFNetwork
:NSURL*的底层,纯C语言
第三方框架
-
ASIHttpRequest
:外号“HTTP终结者”,功能极其强大,可惜早已停止更新 -
AFNetworking
:简单易用,提供了基本够用的常用功能,维护和使用者多 -
MKNetworkKit
:简单易用,产自三哥的故乡印度,维护和使用者少
五、NSURLConnection的简单使用
参考网址:http://www.jianshu.com/p/f291ee58c012
5.1、NSURLConnection同步操作
sendSynchronousRequest:阻塞式的方法,会卡住线程
//1.确定请求路径
NSString *url = @"http://192.168.5.108:8668/jeeplus";
//中文编码
NSString *urlPath = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//URL
NSURL *URL = [NSURL URLWithString:urlPath];
//2.创建一个请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
//超时3S
request.timeoutInterval = 3;
//请求方式
request.HTTPMethod = @"GET";
[request setValue:@"Upgrade" forHTTPHeaderField:@"Connection"];
[request setValue:@"websocket" forHTTPHeaderField:@"Upgrade"];
[request setValue:@"13" forHTTPHeaderField:@"Sec-WebSocket-Version"];
[request setValue:[self ret16bitString] forHTTPHeaderField:@"Sec-WebSocket-Key"];
//2.2设置请求体
request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];
//同步
//3.把请求发送给服务器
NSURLResponse * response;
NSError * error;
/*
第一个参数:请求对象
第二个参数:响应头信息,当该方法执行完毕之后,该参数被赋值
第三个参数:错误信息,如果请求失败,则error有值
*/
NSData * backData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (error) {
NSLog(@"【握手请求】error : %@",[error localizedDescription]);
}else{
NSLog(@"【握手请求】response : %@",response);
NSLog(@"【握手请求】backData : %@",[[NSString alloc]initWithData:backData encoding:NSUTF8StringEncoding]);
NSDictionary *dictData = [NSJSONSerialization JSONObjectWithData:backData options:kNilOptions error:nil];
NSLog(@"【握手请求】msg is %@",[dictData objectForKey:@"msg"]);
}
5.2、NSURLConnection异步操作
sendAsynchronousRequest:不会卡住当前线程,网络请求任务是异步执行的
//1.确定请求路径
NSString *url = @"http://192.168.5.108:8668/jeeplus";
//中文编码
NSString *urlPath = [url stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//URL
NSURL *URL = [NSURL URLWithString:urlPath];
//2.创建一个请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//2.1更改请求方法
request.HTTPMethod = @"POST";
//2.2设置请求体
request.HTTPBody = [@"username=520it&pwd=520it" dataUsingEncoding:NSUTF8StringEncoding];
//3.把请求发送给服务器,发送一个异步请求
/*
第一个参数:请求对象
第二个参数:回调方法在哪个线程中执行,如果是主队列则block在主线程中执行,非主队列则在子线程中执行
第三个参数:completionHandlerBlock块:接受到响应的时候执行该block中的代码
response:响应头信息
data:响应体
connectionError:错误信息,如果请求失败,那么该参数有值
*/
NSOperationQueue * queue = [NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * __nullable response, NSData * __nullable data, NSError * __nullable connectionError) {
//4.解析服务器返回的数据
NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//转换并打印响应头信息
NSHTTPURLResponse *r = (NSHTTPURLResponse *)response;
NSLog(@"--%zd---%@--",r.statusCode,r.allHeaderFields);
}];
六、NSURLSession的简介与使用
参考网址:http://www.jianshu.com/p/02a5a896c9ed
http://www.cocoachina.com/ios/20160601/16544.html
http://www.cnblogs.com/wendingding/p/5168772.html
http://www.jianshu.com/p/fafc67475c73
6.1、知识点
简介:在iOS9.0之后,以前使用的NSURLConnection过期,苹果推荐使用NSURLSession来替换NSURLConnection完成网路请求相关操作。
NSURLSession
NSURLSessionConfiguration
NSURLSessionTask的三个子类:
NSURLSessionDataTask //一般的get、post等请求
NSURLSessionUploadTask // 用于上传文件或者数据量比较大的请求
NSURLSessionDownloadTask //用于下载文件或者数据量比较大的请求
task的三个函数
- (void)suspend;//暂停
- (void)resume;//开始或者恢复
- (void)cancel;//关闭任务
6.2、NSURLSessionConfiguration
简单地说,就是session的配置信息.
#方式一:采用苹果提供的共享session,不做任何修改
NSURLSession *sharedSession = [NSURLSession sharedSession];
#方式二:通过NSURLSessionConfiguration方式配置不同的NSURLSession
// 构造NSURLSessionConfiguration
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
//也可以通过NSURLSessionConfiguration统一设置超时时间、请求头等信息
//设置请求超时为10秒钟
configuration.timeoutIntervalForRequest = 10;
//在蜂窝网络情况下是否继续请求(上传或下载)
configuration.allowsCellularAccess = NO;
//配置请求头
configuration.HTTPAdditionalHeaders =@{@"Content-Encoding":@"gzip"};
// 构造NSURLSession,网络会话;
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
6.3、最简单的GET与POST的demo
GET
使用NSURLSession发送GET请求的方法和NSURLConnection类似,整个过程如下:
1)确定请求路径(一般由公司的后台开发人员以接口文档的方式提供),GET请求参数直接跟在URL后面
2)创建请求对象(默认包含了请求头和请求方法【GET】),此步骤可以省略
3)创建会话对象(NSURLSession)
4)根据会话对象创建请求任务(NSURLSessionDataTask)
5)执行Task
6)当得到服务器返回的响应后,解析数据(XML|JSON|HTTP)
发送GET的方法一:dataTaskWithRequest
-(void)get1
{
//对请求路径的说明
//http://120.25.226.186:32812/login?username=520it&pwd=520&type=JSON
//协议头+主机地址+接口名称+?+参数1&参数2&参数3
//协议头(http://)+主机地址(120.25.226.186:32812)+接口名称(login)+?+参数1(username=520it)&参数2(pwd=520)&参数3(type=JSON)
//GET请求,直接把请求参数跟在URL的后面以?隔开,多个参数之间以&符号拼接
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//2.创建请求对象
//请求对象内部默认已经包含了请求头和请求方法(GET)
NSURLRequest *request = [NSURLRequest requestWithURL:url];
//3.获得会话对象
NSURLSession *session = [NSURLSession sharedSession];
//4.根据会话对象创建一个Task(发送请求)
/*
第一个参数:请求对象
第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
data:响应体信息(期望的数据)
response:响应头信息,主要是对服务器端的描述
error:错误信息,如果请求失败,则error有值
*/
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error == nil) {
//6.解析服务器返回的数据
//说明:(此处返回的数据是JSON格式的,因此使用NSJSONSerialization进行反序列化处理)
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"%@",dict);
}
}];
//5.执行任务
[dataTask resume];
}
发送GET方法二:dataTaskWithURL
-(void)get2
{
//1.确定请求路径
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login?username=520it&pwd=520it&type=JSON"];
//2.获得会话对象
NSURLSession *session = [NSURLSession sharedSession];
//3.根据会话对象创建一个Task(发送请求)
/*
第一个参数:请求路径
第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
data:响应体信息(期望的数据)
response:响应头信息,主要是对服务器端的描述
error:错误信息,如果请求失败,则error有值
注意:
1)该方法内部会自动将请求路径包装成一个请求对象,该请求对象默认包含了请求头信息和请求方法(GET)
2)如果要发送的是POST请求,则不能使用该方法
*/
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//5.解析数据
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"%@",dict);
}];
//4.执行任务
[dataTask resume];
}
POST
使用NSURLSession发送POST请求的方法和NSURLConnection类似,整个过程如下:
1)确定请求路径(一般由公司的后台开发人员以接口文档的方式提供)
2)创建可变的请求对象(因为需要修改),此步骤不可以省略
3)修改请求方法为POST
4)设置请求体,把参数转换为二进制数据并设置请求体
5)创建会话对象(NSURLSession)
6)根据会话对象创建请求任务(NSURLSessionDataTask)
7)执行Task
8)当得到服务器返回的响应后,解析数据(XML|JSON|HTTP)
由于POST需要修改“请求对象”参数,所以只能dataTaskWithRequest
-(void)post
{
//对请求路径的说明
//http://120.25.226.186:32812/login
//协议头+主机地址+接口名称
//协议头(http://)+主机地址(120.25.226.186:32812)+接口名称(login)
//POST请求需要修改请求方法为POST,并把参数转换为二进制数据设置为请求体
//1.创建会话对象
NSURLSession *session = [NSURLSession sharedSession];
//2.根据会话对象创建task
NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/login"];
//3.创建可变的请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//4.修改请求方法为POST
request.HTTPMethod = @"POST";
//5.设置请求体
request.HTTPBody = [@"username=520it&pwd=520it&type=JSON" dataUsingEncoding:NSUTF8StringEncoding];
//6.根据会话对象创建一个Task(发送请求)
/*
第一个参数:请求对象
第二个参数:completionHandler回调(请求完成【成功|失败】的回调)
data:响应体信息(期望的数据)
response:响应头信息,主要是对服务器端的描述
error:错误信息,如果请求失败,则error有值
*/
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//8.解析数据
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSLog(@"%@",dict);
}];
//7.执行任务
[dataTask resume];
}
6.4 NSURLSessionDataDelegate
#这里的代理方法只是简单的阐述下,具体的可以看参考文档
如果项目需要在网络请求数据的过程中,要做进一步的处理的话,需要调用NSURLSession的代理方法。
通常,使用代理方法需要先设置代理对象,但是通过查看NSURLSessionDataDelegate文档,我们可以看到如下,代理属性delegate为只读状态。
@property (nullable, readonly, retain) id delegate;
// 1.delegateQueue参数表示协议方法将会在(NSOperationQueue)队列里面执行。(session的delegate属性是只读的,所以使用如下方法设置代理。)
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
// 2.创建任务(因为要使用代理方法,就不需要block方式的初始化了)
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"http://172.16.2.254/php/phonelogin?yourname=%@&yourpass=%@&btn=login",yourname,yourpass]];
NSURLSessionDataTask *task = [session dataTaskWithRequest:[NSURLRequest requestWithURL:url]];
// 3.执行任务
[task resume];
关于代理行为:
#pragma mark -- NSURLSessionDataDelegate// 1.接收到服务器的响应
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler {
//【注意:此处需要允许处理服务器的响应,才会继续加载服务器的数据。 若在接收响应时需要对返回的参数进行处理(如获取响应头信息等),那么这些处理应该放在这个允许操作的前面。】
completionHandler(NSURLSessionResponseAllow);
}
// 2.接收到服务器的数据(此方法在接收数据过程会多次调用)
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
// 处理每次接收的数据,例如每次拼接到自己创建的数据receiveData
[self.receiveData appendData:data];
}
// 3.3.任务完成时调用(如果成功,error == nil)
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
if(error == nil){
/*
请求完成,成功或者失败的处理
*/
}
else{
NSLog(@"请求失败:%@",error);
}
}