0.iOS的网络请求方式
有GET请求,POST请求,区别如下:
<1>Get是拿数据,对服务器来说,相对安全;
Post是先传数据,然后再拿数据,对服务器来说,相对不安全
<2>Get 请求参数欠安全,参数暴露在外面,
Post 请求参数更安全,看不见参数
<3>Post有数据体,服务器接收到数据体,对数据体做解析,再根据数据体内容,返回一个结果给客户端
1.网络请求的步骤:
<1>地址NSURL
<2>请求NSURLRequest
<3>建立并启动连接NSURLConnection
<4>使用NSURLConnectionDataDelegate处理服务器返回的结果
2.GET请求
// 1. 确定地址NSURL
NSString *urlStr = [NSString stringWithFormat:@"http://www.baidu.com/login.php?username=%@&password=%@", userName, pwd];
// 1.1 url含中文,故需要对urlStr转码
urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString:urlStr];
// 2. 设置请求NSURLRequest
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 3. 建立并启动连接NSURLConnection
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
// 3.1 启动连接,异步连接请求
[conn start];
// 服务器通知准备,准备中转数据,把下面这句放在这,性能更好
self.serverData= [NSMutableData data];
#pragma mark - 网络代理方法
#pragma mark 1. 接收到服务器的响应,服务器要传数据,客户端做接收准备
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
<span style="white-space:pre"> </span>NSLog(@"response --> %@", response); // 准备中转数据,下面这句放在这,不太好,建议拿出来
<span style="white-space:pre"> </span>// self.serverData= [NSMutableData data];
}
#pragma mark 2. 接收服务器传输的数据,可能会多次执行
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
<span style="white-space:pre"> </span>// 对每次传输的数据进行拼接,需要中转数据(属性)
<span style="white-space:pre"> </span>[self.serverData appendData:data];
}
#pragma mark 3. 接收数据完成,做后续处理
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
<span style="white-space:pre"> </span>// 对方法2拼接的数据Á,做后续处理即可
<span style="white-space:pre"> </span>NSString *str = [[NSString alloc]initWithData:self.serverData encoding:NSUTF8StringEncoding];
<span style="white-space:pre"> </span>// 打印从服务器端接收的数据
<span style="white-space:pre"> </span>NSLog(@"%@",str);
<span style="white-space:pre"> </span>// 清空数据
<span style="white-space:pre"> </span>self.serverData = nil;
}
#pragma mark 4. 服务器请求失败,原因很多(网络环境等等)
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
<span style="white-space:pre"> </span>NSLog(@"网络请求错误:%@", error.localizedDescription);
}
3.POST请求
// 1. 确定地址NSURL
NSString *urlString = [NSString stringWithFormat:@"http://www.baidu.com/login.php"];
NSURL *url = [NSURL URLWithString:urlString];
// 2. 建立请求NSURLRequest(POST),和GET请求相比,Request是可变的
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 1) 请求方式
[request setHTTPMethod:@"POST"];
// 2) 数据体,POST请求中创建数据体时,如果有中文,不需要转换
// 因为dataUsingEncoding已经实现了转码
NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@", userName, pwd];
// 将NSString转换为NSData
NSData *body = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:body];
// 3. 建立并启动连接NSURLConnection
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request delegate:self];
// 启动连接,异步连接请求
[conn start];
// 先准备好中转数据,供代理方法使用
self.serverData = [NSMutableData data];
3.2POST请求比GET请求,多一个代理方法,这个代理方法只适用于POST.商业应用中,这个代理方法用的少,因为第三方框架可以替代
#pragma mark 向服务器发送数据,此方法仅适用于POST,尤其上传文件
- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
NSLog(@"发送数据给服务器");
}
4.如果同一时间有多个请求,并且每个请求的后续处理都不一样.怎么办?
每一个发送到服务器的请求,都会回调那几个代理方法,如果还是通过代理方法去实现,就不太好了.
能不能在设置request时,就同时设置好当前request的后续处理? 可以,见下文
4.1 POST请求--同步请求
// 1. 确定地址NSURL
NSString *urlString = [NSString stringWithFormat:@"http://www.baidu.com/login.php"];
NSURL *url = [NSURL URLWithString:urlString];
// 2. 建立请求NSURLRequest(POST),和GET请求相比,Request是可变的
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 1) 请求方式
[request setHTTPMethod:@"POST"];
// 2) 数据体,POST请求中创建数据体时,如果有中文,不需要转换
// 因为dataUsingEncoding已经实现了转码
NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@", userName, pwd];
// 将NSString转换为NSData
NSData *body = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:body];
// 3. 同步请求<p style="margin-top: 0px; margin-bottom: 0px;"> NSURLResponse *response = nil;</p><p style="margin-top: 0px; margin-bottom: 0px;"> NSError *error = nil;</p><p style="margin-top: 0px; margin-bottom: 0px; min-height: 13px;"> </p><p style="margin-top: 0px; margin-bottom: 0px;"> // 同步操作没有完成,后面的代码不会执行</p><p style="margin-top: 0px; margin-bottom: 0px;"> NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];</p><p style="margin-top: 0px; margin-bottom: 0px; min-height: 13px;"> </p><p style="margin-top: 0px; margin-bottom: 0px;"> // 1> 接收到数据,表示工作正常</p><p style="margin-top: 0px; margin-bottom: 0px;"> // 2> 没有接收到数据,但是error为nil,表示接收到空数据</p><p style="margin-top: 0px; margin-bottom: 0px;"> // 通常服务器没有对该请求做任何响应</p><p style="margin-top: 0px; margin-bottom: 0px;"> // 3> error不为空,表示请求出错</p><p style="margin-top: 0px; margin-bottom: 0px;"> if (data != nil) {</p><p style="margin-top: 0px; margin-bottom: 0px;"> NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];</p><p style="margin-top: 0px; margin-bottom: 0px;"> NSLog(@"%@", str);</p><p style="margin-top: 0px; margin-bottom: 0px;"> } else if (data == nil && error == nil) {</p><p style="margin-top: 0px; margin-bottom: 0px;"> NSLog(@"接收到空数据");</p><p style="margin-top: 0px; margin-bottom: 0px;"> } else {</p><p style="margin-top: 0px; margin-bottom: 0px;"> NSLog(@"%@", error.localizedDescription);</p><p style="margin-top: 0px; margin-bottom: 0px;"> }</p>
// 1. 确定地址NSURL
NSString *urlString = [NSString stringWithFormat:@"http://www.baidu.com/login.php"];
NSURL *url = [NSURL URLWithString:urlString];
// 2. 建立请求NSURLRequest(POST),和GET请求相比,Request是可变的
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
// 1) 请求方式
[request setHTTPMethod:@"POST"];
// 2) 数据体,POST请求中创建数据体时,如果有中文,不需要转换
// 因为dataUsingEncoding已经实现了转码
NSString *bodyStr = [NSString stringWithFormat:@"username=%@&password=%@", userName, pwd];
// 将NSString转换为NSData
NSData *body = [bodyStr dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:body];
// 异步请求
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *reponse, NSData *data, NSError *error) {
if (data != nil) {
NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"%@", str);
} else if (data == nil && error == nil) {
NSLog(@"接收到空数据");
} else {
NSLog(@"%@", error.localizedDescription);
}
}];