iOS网络请求 get - post 区别

字数 3754阅读 381

同步请求可以从因特网请求数据, 一旦发送同步请求,程序将停止用户交互,直至服务器返回数据完成, 才可以进行下一步操作

异步请求不会阻塞主线程, 而会建立一个新的线程来操作, 用户发出异步请求后, 依然可以对 UI 进行操作, 程序可以继续运行

GET请求, 将参数直接写在访问路径上. 操作简单, 不过容易让外界看到, 安全性不高, 地址最多 255 字节.

POST 请求, 将参数放到 body 里面, POST请求的操作相对复杂, 需要将参数和地址分开, 不过安全性高,参数放在body里面, 不容易被捕获.

//开发中不推荐使用同步网络请求

1. 同步GET请求

//第一步:  创建 URL

//地址字符串

NSString *urlString = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";

//统一资源定位符(URL)

NSURL *url = [NSURL URLWithString:urlString];

其中缓存协议是个枚举类型包含:

NSURLRequestUseProtocolCachePolicy(基础策略)

NSURLRequestReloadIgnoringLocalCacheData(忽略本地缓存) √

NSURLRequestReturnCacheDataElseLoad(首先使用缓存,如果没有本地缓存,才从原地址下载)

NSURLRequestReturnCacheDataDontLoad(使用本地缓存,从不下载,如果本地没有缓存,则请求失败,此策略多用于离线操作    √

NSURLRequestReloadIgnoringLocalAndRemoteCacheData(无视任何缓存策略,无论是本地的还是远程的,总是从原地址重新下载)

NSURLRequestReloadRevalidatingCacheData(如果本地缓存是有效的则不下载,其他任何情况都从原地址重新下载)√

2.//第一个参数:统一资源定位符(请求访问路径)

//第二个参数:缓存策略(缓存协议)

//第三个参数:超时时间(网络请求超时时间)

NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60.0f];

3. 连接服务器

//NSURLConnection 在iOS9.0之后, 不推荐使用了

//第一个参数:NSURLRequest 类型的对象

//第二个参数:存储的是一些网络请求的信息,一般为nil(包体)

//第三个参数:错误信息

NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];  //从网上请求得到的数据

NSString *str = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];  //转码之后,可以打印出来

NSLog(@"str == %@", str); //打印

拓展 ----此外: 可以将获取到的数据, 进行解析 ----

//解析数据

//用字典接收数据, 并且打印  ----->这里用什么接收要看解析内容的结构的 ---

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];

NSLog(@"dic === %@", dic);

POST 同步

//第一步,创建URL

NSURL *url = [NSURL URLWithString:@"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx"];

//第二步,创建请求

NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];

[request setHTTPMethod:@"POST"];//设置请求方式为POST,默认为GET

NSString *str = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";//设置参数 (创建一个字符串, 这个是后台告诉的)

NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding]; //将这个字符串转换成 NSData 类型的对象, (data 是上传的数据)

//设置请求方式 方式为大写的 如 :POST GET

//如果是GET 请求可以不设置,但是POST请求必须设置

[urlRequest setHTTPMethod:@"POST"];

//把需要上传的data放进request里面

[request setHTTPBody:data];

//第三步,连接服务器

//NSURLConnection 在iOS9.0之后, 不推荐使用了

//第一个参数:NSURLRequest 类型的对象

//第二个参数:存储的是一些网络请求的信息,一般为nil(包体)

//第三个参数:错误信息

NSData *received = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];    //从网上请求得到的数据

NSString *str1 = [[NSString alloc]initWithData:received encoding:NSUTF8StringEncoding]; //转码

NSLog(@"%@",str1); //打印

拓展 ----此外: 可以将获取到的数据, 进行解析 ----

//解析数据

//用字典接收数据, 并且打印  ----->这里用什么接收要看解析内容的结构的 ---

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:received options:NSJSONReadingAllowFragments error:nil];

NSLog(@"dic === %@", dic);

GET 异步 --->代理的方式 ---

//第一步,创建url

NSString *urlString = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";

NSURL *url = [NSURL URLWithString:urlString];

//第二步,创建请求

//NSURLRequest *request = [NSMutableURLRequest requestWithURL:url];

NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];

//第三步,连接服务器 --->代理的异步网络请求(GET)----

//第一个参数 : NSURLRequest

//第二个参数 : 代理人

NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];

//接收到服务器回应的时候调用此方法

//服务器开始响应

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

//初始化保存结果的data

self.resultData = [NSMutableData data];

}

//接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次

//接收到数据

//这个方法会重复执行,所以可能拿到一段一段的数据,这就需要我们把这些数据拼接起来

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

// 为了防止拿到的数据不全, 所以把拿到的数据拼接到保存结果的data中.

[self.resultData appendData:data];

}

//数据传完之后调用此方法

//结束响应

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.resultData options:NSJSONReadingAllowFragments error:nil];

NSLog(@"dic === %@", dic);

//更新数据源数组

//刷新UI

}

//网络请求过程中,出现任何错误(断网,连接超时等)会进入此方法

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

NSLog(@"%@",[error localizedDescription]);

}

GET 异步 --->Block的方式 ---

//第一步,创建url

NSString *urlString = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx?date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";

NSURL *url = [NSURL URLWithString:urlString];

//第二步,创建请求

//NSURLRequest *request = [NSMutableURLRequest requestWithURL:url];

NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];

//第三步,连接服务器 ---> Block的方法 ---

//调用带有block回调的方法,执行网络请求

// 第一个参数: NSURLRequest

// 第二个参数: block块里面的代码在哪个线程执行 (新添加的线程)

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

//response : 携带是接口的一些信息 header

//data : 请求下来的数据,需要使用的

//connectionError : 错误信息

#warning 不要在子线程更新UI,在主线程更新

if (connectionError == nil) {

//这里应该刷新UI了

//1.给数据源数组赋值

//2,赋值结束之后.刷新UI([self.tableView reloadData])

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];

NSLog(@"dic == %@",dic);

}

}];

POST 异步 ----> 代理的方法 ---

//第一步,创建url

NSString *urlString = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";

NSURL  *url = [NSURL URLWithString:urlString];

//第二步,创建请求

NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

NSString *dataString = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";

NSData *postData = [dataString dataUsingEncoding:NSUTF8StringEncoding];

[urlRequest setHTTPMethod:@"POST"];

[urlRequest setHTTPBody:postData];

//第三步,连接服务器 --->代理的方式 ---

[NSURLConnection connectionWithRequest:urlRequest delegate:self];

//接收到服务器回应的时候调用此方法

//服务器开始响应

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

{

//初始化保存结果的data

self.resultData = [NSMutableData data];

}

//接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次

//接收到数据

//这个方法会重复执行,所以可能拿到一段一段的数据,这就需要我们把这些数据拼接起来

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

{

// 为了防止拿到的数据不全, 所以把拿到的数据拼接到保存结果的data中.

[self.resultData appendData:data];

}

//数据传完之后调用此方法

//结束响应

- (void)connectionDidFinishLoading:(NSURLConnection *)connection

{

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:self.resultData options:NSJSONReadingAllowFragments error:nil];

NSLog(@"dic === %@", dic);

//更新数据源数组

//刷新UI

}

//网络请求过程中,出现任何错误(断网,连接超时等)会进入此方法

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

{

NSLog(@"%@",[error localizedDescription]);

}

POST异步 ---> Block 的方法----

//第一步,创建url

NSString *urlString = @"http://ipad-bjwb.bjd.com.cn/DigitalPublication/publish/Handler/APINewsList.ashx";

NSURL  *url = [NSURL URLWithString:urlString];

//第二步,创建请求

NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:url];

NSString *dataString = @"date=20131129&startRecord=1&len=5&udid=1234567890&terminalType=Iphone&cid=213";

NSData *postData = [dataString dataUsingEncoding:NSUTF8StringEncoding];

[urlRequest setHTTPMethod:@"POST"];

[urlRequest setHTTPBody:postData];

//第三步,连接服务器 --->block---

//调用带有block回调的方法,执行网络请求

// 第一个参数: NSURLRequest

// 第二个参数: block块里面的代码在哪个线程执行 (新添加的线程)

[NSURLConnection sendAsynchronousRequest:urlRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {

//response : 携带是接口的一些信息 header

//data : 请求下来的数据,需要使用的

//connectionError : 错误信息

#warning 不要在子线程更新UI,在主线程更新

if (connectionError == nil) {

//这里应该刷新UI了

//1.给数据源数组赋值

//2,赋值结束之后.刷新UI([self.tableView reloadData])

NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];

NSLog(@"dic == %@",dic);

}

}];

从表面的意思看get 和 post的区别get就是获取数据,post就是发送数据。这个是误区。其实两者都可以的,在IOS向服务器发送请求里面可以带参数。

那么这些误区是怎么出现的呢?先看看一下对http的解释

一般在浏览器中输入网址访问资源都是通过GET方式;在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认为GET提交

Http定义了与服务器交互的不同方法,最基本的方法有4种,分别是GET,POST,PUT,DELETE

URL全称是资源描述符,我们可以这样认为:一个URL地址,它用于描述一个网络上的资源,而HTTP中的GET,POST,PUT,DELETE就对应着对这个资源的查 ,改 ,增 ,删 4个操作。到这里,大家应该有个大概的了解了,GET一般用于获取/查询 资源信息,而POST一般用于更新 资源信息(个人认为这是GET和POST的本质区别,也是协议设计者的本意,其它区别都是具体表现形式的差异 )。

再进一步了解下他们两个的区别:

GET使用URL或Cookie传参。而POST将数据放在BODY中。

GET的URL会有长度上的限制,则POST的数据则可以非常大。

POST比GET安全,因为数据在地址栏上不可见。

这些也是有点误区的,就像同步请求一定的慢吗?

GET和POST与数据如何传递没有关系?

GET和POST是由HTTP协议定义的。在HTTP协议中,Method和Data(URL, Body, Header)是正交的两个概念,也就是说,使用哪个Method与应用层的数据如何传输是没有相互关系的。

HTTP没有要求,如果Method是POST数据就要放在BODY中。也没有要求,如果Method是GET,数据(参数)就一定要放在URL中而不能放在BODY中。

那么,网上流传甚广的这个说法是从何而来的呢?我在HTML标准中,找到了相似的描述。这和网上流传的说法一致。但是这只是HTML标准对HTTP协议的用法的约定。怎么能当成GET和POST的区别呢?

而且,现代的Web Server都是支持GET中包含BODY这样的请求。虽然这种请求不可能从浏览器发出,但是现在的Web Server又不是只给浏览器用,已经完全地超出了HTML服务器的范畴了。

HTTP协议对GET和POST都没有对长度的限制?

HTTP协议明确地指出了,HTTP头和Body都没有长度的要求。而对于URL长度上的限制,有两方面的原因造成:

浏览器。据说早期的浏览器会对URL长度做限制。据说IE对URL长度会限制在2048个字符内(流传很广,而且无数同事都表示认同)。但我自己试了一下,我构造了90K的URL通过IE9访问live.com,是正常的。网上的东西,哪怕是Wikipedia上的,也不能信。

服务器。URL长了,对服务器处理也是一种负担。原本一个会话就没有多少数据,现在如果有人恶意地构造几个几M大小的URL,并不停地访问你的服务器。服务器的最大并发数显然会下降。另一种攻击方式是,把告诉服务器Content-Length是一个很大的数,然后只给服务器发一点儿数据,嘿嘿,服务器你就傻等着去吧。哪怕你有超时设置,这种故意的次次访问超时也能让服务器吃不了兜着走。有鉴于此,多数服务器出于安全啦、稳定啦方面的考虑,会给URL长度加限制。但是这个限制是针对所有HTTP请求的,与GET、POST没有关系。这个貌似听着对点吧。

3.对于安全不安全讲。

get:

.所谓安全的意味着该操作用于获取信息而非修改信息。换句话说,GET请求一般不应产生副作用。就是说,它仅仅是获取资源信息,就像数据库查询一样,不会修改,增加数据,不会影响资源的状态。

注意:这里安全的含义仅仅是指是非修改信息。

POST的安全性要比GET的安全性高。注意:这里所说的安全性和上面GET提到的“安全”不是同个概念。上面“安全”的含义仅仅是不作数据修改,而这里安全的含义是真正的Security的含义,比如:通过GET提交数据,用户名和密码将明文出现在URL上,因为(1)登录页面有可能被浏览器缓存, (2)其他人查看浏览器的历史纪录,那么别人就可以拿到你的账号和密码了,除此之外,使用GET提交数据还可能会造成Cross-site request forgery攻击 .

看出来区别了吧

推荐阅读更多精彩内容