网络编程(一) GET / POST请求与NSURLConnection 使用

一、HTTP 协议
 
1、URL :同一资源定位符,每个 URL 对应互联网上唯一的资源,格式:协议://主机地址/路径
 
2、URL 使用的协议有:
HTTP:超文本传输协议
file:访问本地计算机上的资源(不需要主机地址)
mailto:访问电子邮价地址
FTP:访问共享主机的文件
 
一、HTTP 通信包含2个过程:请求、响应
 
1、请求需要以下内容:
 
  • 请求行:包括请求方法、请求资源路径、HTTP协议版本
 
例如:GET /resource/images/1.png HTTP/1.1
 
  • 请求头:包括对客户端环境描述、客户端请求的主机地址
 
Host: 192.168.1.78:8080          请求的主机地址
User-Agent: Chrome/33.2          客户端环境描述
Accept: text/html                客户端可以接受的数据类型
 
  • 请求体:客户端发给服务器的数据
 
2、响应需要包含以下内容:
 
  • 状态行:包含HTTP协议版本、状态码、状态英文名称
 HTTP/1.1 200 OK
 
  • 响应头:包含对服务器的描述、对返回数据的描述
server: Apache-Coyote/1.2
Content-Type: image/jpeg
 
  • 实体内容:服务器返回给客户端的具体数据
 
 
技术分享
 
在 iOS 开发中不论使用 GET/POST 方法访问服务器都不需要使用请求头、请求行,GET 方法本来就不需要请求体,POST 方法需要请求体,因为上传大数据只能使用 POST 方法
 
 
二、NSURLConnection 使用 GET / POST 请求
 
GET / POST 区别:
 
(1)、GET 参数都拼接在 URL 后面,参数有限制
(2)、POST 参数都在请求体,参数没有限制
 
在 iOS 中发送这2种请求都是使用 NSURLConnection 来实现的,分别有3种方法
 
3、步骤:
(1)、创建一个 NSURL 对象,设置请求路径
(2)、使用 NSURL 创建一个 NSURLRequest 对象,设置请求头和请求体
(3)、使用 NSURLConnection 发送 NSURLRequest 
NSURLConnection 发送请求的方式有2种:同步(在主线程中执行)、异步(开启新线程执行,异步又分为2种方法)
 
4、使用 NSURLConnection 实现 GET 请求的方法:
(1)、同步请求(不推荐使用):
 
1     //创建一个 NSURL 对象,设置请求路径
2     NSString *string = [NSString stringWithFormat: @"http://www.baidu.com"];
3     NSURL *url = [NSURL URLWithString: string];
4    
5     //使用 NSURL 创建一个 NSURLRequest 对象,设置请求头和请求体
6     NSURLRequest *request = [NSURLRequest requestWithURL: url];
7    
8     //使用 NSURLConnection 发送 NSURLRequest,同步请求
9     NSData *data = [NSURLConnection sendSynchronousRequest: request returningResponse:nil error: nil];

 

 
(2)、Block 异步请求:
 
1     //异步请求,在子线程中执行
2     NSOperationQueue *queue = [[NSOperationQueue alloc] init];
3     [NSURLConnection sendAsynchronousRequest: request queue: queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
4        
5         //当服务器有返回数据时调用
6        
7     }];

 

 
(3)、代理异步请求:
 
首先实现代理协议:
 
NSURLConnectionDataDelegate
 
//用来存放服务器返回的所有数据
@property (nonatomic, strong) NSMutableData *responseData;

 

 
执行代理异步请求:
 
    //执行代理异步请求,三种方法都可以实现
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest: request delegate: self startImmediately: YES];
    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest: request delegate:self];
    NSURLConnection *connection = [NSURLConnection connectionWithRequest: request delegate: self];

 

 
这里第一种方法的 startImmediately 参数默认是 YES ,若写NO 则需要调用 start 方法才能执行
 
 
1    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest: request delegate: self startImmediately: NO];
2     [connection start];

 

 
实现代理方法:
 
#pragma mark - NSURLConnectionDataDelegate 代理方法
/**
 *  请求错误时候调用(请求超时\断网\没有网, 一般指客户端错误)
 */
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
}

/**
 *  当接受到服务器的响应也即连通了服务器就会调用
 */
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
       //这里一般用于初始化数据
     self.responseData = [NSMutableData data];
}

/**
 *  当接受到服务器的数据就会调用,可能会被调用多次, 每次调用只会传递部分数据
 */
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
      //这里一般用于数据的拼接,不能用于处理数据,因为数据并未完全接受全
    [self.responseData appendData:data];
}

/**
 *  当服务器的数据接受完毕后就会调用
 */
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
     //这里用于处理数据
}

 

 
4、使用 NSURLConnection 实现 POST 请求方法:
 
(1)、同步请求:
(2)、Block 异步请求:
 
 1  //设置请求路径
 2     NSURL *url = [NSURL URLWithString:@“http://www.baidu.com"];
 3    
 4     //创建请求对象
 5     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // 默认就是GET请求
 6     request.timeoutInterval = 5; // 设置请求超时
 7     request.HTTPMethod = @"POST"; // 设置为POST请求
 8    
 9     // 通过请求头告诉服务器客户端的类型
10     [request setValue:@"ios" forHTTPHeaderField:@"User-Agent"];
11    
12     // 设置请求体
13     NSString *param = [NSString stringWithFormat:@"username=%@&pwd=%@", username, pwd];
14     request.HTTPBody = [param dataUsingEncoding:NSUTF8StringEncoding];
15  
16        // 异步发送请求
17     NSOperationQueue *queue = [NSOperationQueue mainQueue];
18     [NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {  
19  
20     }];

 

     
 
(3)、代理异步请求:
 
三、HEAD 请求
 
GET / POST 请求一般都是直接下载数据,但有时候想要不下载数据而知道这个数据的大小,这时候可使用时 HEAD 请求,该请求可以直接获取响应的响应头,从而获知数据大小
 
1    //使用 HEAD 请求
2     NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.url]];
3     request.HTTPMethod = @"HEAD";
4    
5     //获取响应头
6     NSURLResponse *response = nil;
7     [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
8     self.totalLength = response.expectedContentLength;

 

   
 
四、缓存的使用
 
当一个 URL 可能需要多次请求时,为防止重复发起请求浪费资源,可以使用缓存保存数据,下次直接调用缓存从而避免多次请求
 
  • 客户端第一次请求某数据时:
 
技术分享
 
  • 服务器响应客户端:
 
技术分享
 
  • 客户端再次请求某数据时:
 
技术分享
 
技术分享
 
 
使用 NSURLCache 实现缓存,NSURLCache 是单例的,默认只缓存 GET 请求 POST 请求不能缓存,可以设置内存缓存、硬盘缓存的最大容量,硬盘的缓存放在 /Library/Caches 中。
 
  • 使用时只需设置请求的缓存策略:
 
  // 设置缓存策略(有缓存就用缓存,没有缓存就重新请求)
    request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;

 

 
  • 因为一个 NSURLConnection 对应一个 NSURLResponse ,所以想要获取某一个请求的数据时只需要找出它所对应的响应即可:
 
 1     // 获得全局的缓存对象
 2     NSURLCache *cache = [NSURLCache sharedURLCache];
 3    
 4     //请求对应的响应
 5     NSCachedURLResponse *response = [cache cachedResponseForRequest:request];
 6    
 7     //判断是否有缓存
 8     if (response) {
 9         //有缓存
10     } else {
11        //没有缓存
12     }

 

 
 
  • 想要更新某个请求的数据时,需要删除其对应的缓存:
 
    //清楚某个指定请求的缓存
    [cache removeCachedResponseForRequest: request];
   
    //清楚所有缓存
    [cache removeAllCachedResponses];

 

 
使用缓存需要注意几点:
 
  • 经常更新的数据不能使用缓存
  • 不常更新的数据可以定期更改缓存策略或清楚缓存,以便更新数据
 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。