iOS開(kāi)發(fā)網(wǎng)絡(luò)篇—GET請(qǐng)求和POST請(qǐng)求
目前創(chuàng)新互聯(lián)已為數(shù)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計(jì)、吉水網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。
一、GET請(qǐng)求和POST請(qǐng)求簡(jiǎn)單說(shuō)明
創(chuàng)建GET請(qǐng)求
1 // 1.設(shè)置請(qǐng)求路徑
2 NSString *urlStr=[NSString stringWithFormat:@";pwd=%@",self.username.text,self.pwd.text];
3 NSURL *url=[NSURL URLWithString:urlStr];
4
5 // 2.創(chuàng)建請(qǐng)求對(duì)象
6 NSURLRequest *request=[NSURLRequest requestWithURL:url];
7
8 // 3.發(fā)送請(qǐng)求
服務(wù)器:
創(chuàng)建POST請(qǐng)求
1 // 1.設(shè)置請(qǐng)求路徑
2 NSURL *URL=[NSURL URLWithString:@""];//不需要傳遞參數(shù)
3
4 // 2.創(chuàng)建請(qǐng)求對(duì)象
5 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:URL];//默認(rèn)為get請(qǐng)求
6 request.timeoutInterval=5.0;//設(shè)置請(qǐng)求超時(shí)為5秒
7 request.HTTPMethod=@"POST";//設(shè)置請(qǐng)求方法
8
9 //設(shè)置請(qǐng)求體
10 NSString *param=[NSString stringWithFormat:@"username=%@pwd=%@",self.username.text,self.pwd.text];
11 //把拼接后的字符串轉(zhuǎn)換為data,設(shè)置請(qǐng)求體
12 request.HTTPBody=[param dataUsingEncoding:NSUTF8StringEncoding];
13
14 // 3.發(fā)送請(qǐng)求
服務(wù)器:
二、比較
建議:提交用戶的隱私數(shù)據(jù)一定要使用POST請(qǐng)求
相對(duì)POST請(qǐng)求而言,GET請(qǐng)求的所有參數(shù)都直接暴露在URL中,請(qǐng)求的URL一般會(huì)記錄在服務(wù)器的訪問(wèn)日志中,而服務(wù)器的訪問(wèn)日志是黑客攻擊的重點(diǎn)對(duì)象之一
用戶的隱私數(shù)據(jù)如登錄密碼,銀行賬號(hào)等。
三、使用
1.通過(guò)請(qǐng)求頭告訴服務(wù)器,客戶端的類型(可以通過(guò)修改,欺騙服務(wù)器)
1 // 1.設(shè)置請(qǐng)求路徑
2 NSURL *URL=[NSURL URLWithString:@""];//不需要傳遞參數(shù)
3
4 // 2.創(chuàng)建請(qǐng)求對(duì)象
5 NSMutableURLRequest *request=[NSMutableURLRequest requestWithURL:URL];//默認(rèn)為get請(qǐng)求
6 request.timeoutInterval=5.0;//設(shè)置請(qǐng)求超時(shí)為5秒
7 request.HTTPMethod=@"POST";//設(shè)置請(qǐng)求方法
8
9 //設(shè)置請(qǐng)求體
10 NSString *param=[NSString stringWithFormat:@"username=%@pwd=%@",self.username.text,self.pwd.text];
11 //把拼接后的字符串轉(zhuǎn)換為data,設(shè)置請(qǐng)求體
12 request.HTTPBody=[param dataUsingEncoding:NSUTF8StringEncoding];
13
14 //客戶端類型,只能寫英文
15 [request setValue:@"ios+android" forHTTPHeaderField:@"User-Agent"];
服務(wù)器:
2.加強(qiáng)對(duì)中文的處理
問(wèn)題:URL不允許寫中文
在GET請(qǐng)求中,相關(guān)代碼段打斷點(diǎn)以驗(yàn)證。
在字符串的拼接參數(shù)中,用戶名使用“文頂頂”.
轉(zhuǎn)換成URL之后整個(gè)變成了空值。
提示:URL里面不能包含中文。
解決:進(jìn)行轉(zhuǎn)碼
1 // 1.設(shè)置請(qǐng)求路徑
2 NSString *urlStr=[NSString stringWithFormat:@";pwd=%@",self.username.text,self.pwd.text];
3 //轉(zhuǎn)碼
4 urlStr= [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
5 NSURL *url=[NSURL URLWithString:urlStr];
6
7 // 2.創(chuàng)建請(qǐng)求對(duì)象
8 NSURLRequest *request=[NSURLRequest requestWithURL:url];
調(diào)試查看:
服務(wù)器:
兩種請(qǐng)求方式GET,POST
兩種請(qǐng)求方式的比較
相同點(diǎn):都能給服務(wù)器傳輸數(shù)據(jù)
不同點(diǎn):
1、給服務(wù)器傳輸數(shù)據(jù)的方式:
GET:通過(guò)網(wǎng)址字符串。POST:通過(guò)data
2、傳輸數(shù)據(jù)的大小:GET:?址字符串最多255字節(jié)。POST:使用NSData,容量超過(guò)1G
3、安全性:GET:所有傳輸給服務(wù)器的數(shù)據(jù),顯示在網(wǎng)址里,類似于密碼的明文輸入,直接可見(jiàn)。
POST:數(shù)據(jù)被轉(zhuǎn)成NSData(二進(jìn)制數(shù)據(jù)),類似于密碼的密文輸?入,?無(wú)法直接讀取。
連接方式
同步:使用一個(gè)線程(主線程)完成所有的工作,效率低,當(dāng)線程正在執(zhí)行一個(gè)任務(wù)的時(shí)候無(wú)法執(zhí)行另一個(gè)任務(wù),所有如果使用同步進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)的請(qǐng)求,那么在該線程進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí),暫時(shí)無(wú)法響應(yīng)用戶的點(diǎn)擊事件,用戶體驗(yàn)極差
異步:再開(kāi)一個(gè)線程(子線程)去完成任務(wù),此時(shí),主線程依然可以監(jiān)聽(tīng)用戶的點(diǎn)擊事件,不會(huì)造成卡頓,用戶體驗(yàn)較好
Web Service使用的主要協(xié)議是HTTP協(xié)議,即 超文本傳輸協(xié)議 。
HTTP/1.1協(xié)議共定義了8種請(qǐng)求方法(OPTIONS、HEAD、GET、POST、PUT、DELETE、TRACE、CONNECT)作為Web服務(wù)器。
GET方法 ,是向指定的資源發(fā)送請(qǐng)求,請(qǐng)求的參數(shù)“顯式”地在URL的后面。有點(diǎn)像明信片,把內(nèi)容“顯式”寫在外面,因此安全性比較差。一般使用于讀取數(shù)據(jù)、例如從服務(wù)器讀取靜態(tài)圖片、或查詢數(shù)據(jù)等。
POST方法 ,是向指定資源提交數(shù)據(jù),請(qǐng)求服務(wù)器進(jìn)行處理,數(shù)據(jù)包含在 請(qǐng)求體 中。參數(shù)和地址分開(kāi),放在body里面。有點(diǎn)像把信內(nèi)容放在信封中,接觸的人看不到,安全性比較高。一般用于例如提交表單、上傳文件等(請(qǐng)求的的動(dòng)態(tài)資源,與查詢類似,每個(gè)方法調(diào)用都要傳遞很多參數(shù),因此需要使用NSMutableURLRequest創(chuàng)建請(qǐng)求。 )
iOS SDK中為HTTP請(qǐng)求提供了同步和異步請(qǐng)求這兩種不同的API,
同步請(qǐng)求,可以從因特網(wǎng)請(qǐng)求數(shù)據(jù),一旦發(fā)送同步請(qǐng)求,程序?qū)⑼V褂脩艚换?,直至服?wù)器返回?cái)?shù)據(jù)完成,才可以進(jìn)行下一步操作,意味著線程阻塞;
異步請(qǐng)求,不會(huì)阻塞主線程,而會(huì)建立一個(gè)新的線程來(lái)操作,用戶發(fā)出異步請(qǐng)求后,依然可以對(duì)UI進(jìn)行操作,程序可以繼續(xù)運(yùn)行;
它們的主要區(qū)別在于連接方式的不同。
下面通過(guò)請(qǐng)求一個(gè)登陸接口介紹有關(guān)于網(wǎng)絡(luò)請(qǐng)求中的不同情況。
【本次開(kāi)發(fā)環(huán)境: Xcode:7.2 ? ??iOS Simulator:iphone6 ? By:啊左】
一、GET方法
1.同步get方法:
//1.創(chuàng)建一個(gè)web路徑?
NSString*webPath=[NSString?stringWithFormat:@";pass=%@btn=login",yourname,yourpass]; ? ? ?
webPath=[webPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];?//url不允許為中文等特殊字符,需要進(jìn)行字符串的轉(zhuǎn)碼為URL字符串,例如空格轉(zhuǎn)換后為“%20”;? ? ?
NSURL *url=[NSURL URLWithString:webPath];? ? ??
//2.根據(jù)WEB路徑創(chuàng)建一個(gè)請(qǐng)求? ? ?
NSURLRequest? *request=[NSURLRequest requestWithURL:url];? ? ? ? ?
NSURLResponse *respone;//獲取連接的響應(yīng)信息,可以為nil? ? ?
NSError *error;? ? ? ? //獲取連接的錯(cuò)誤時(shí)的信息,可以為nil? ??
//3.得到服務(wù)器數(shù)據(jù)? ??
NSData*data=[NSURLConnection sendSynchronousRequest: request returningResponse: respone error: error];? ??
if(data==nil)? ? {? ? ? ? NSLog(@"登陸失敗:%@,請(qǐng)重試",error);? ? ? ? return;? ? }?
/*? ? ? ? 4.對(duì)服務(wù)器獲取的數(shù)據(jù)data進(jìn)行相應(yīng)的處理;? */
2.異步get方法:
異步請(qǐng)求與同步請(qǐng)求的不同在于使用NSURLConnectionDataDelegate委托協(xié)議,指定代理.
@interface ViewController : UIViewController // 遵循協(xié)議
@property (weak,nonatomic) NSMutableData *receiveData;? //創(chuàng)建一個(gè)可變data,用于異步接收服務(wù)器的數(shù)據(jù)
@end
創(chuàng)建網(wǎng)絡(luò)請(qǐng)求:
//1.創(chuàng)建一個(gè)web路徑
NSString*webPath=[NSString stringWithFormat: @";pass=%@btn=login",yourname,yourpass];
webPath=[webPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL? *url=[NSURL URLWithString:webPath];
//2.根據(jù)WEB路徑創(chuàng)建一個(gè)請(qǐng)求
NSURLRequest *request=[NSURLRequest requestWithURL:url];
//3.指定代理 以異步的方式接收數(shù)據(jù)NSURLConnectionDataDelegate
NSURLConnection? *con=[NSURLConnection connectionWithRequest:request delegate:self];
if(con==nil)
{
NSLog(@"創(chuàng)建連接失敗.");
return;
}
else//成功 準(zhǔn)備接數(shù)據(jù)
{
if(self.receiveData==nil)
{
self.receiveData=[[NSMutableData alloc] init];
}
}
異步的代理行為:
-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{? ??
NSLog(@"已經(jīng)響應(yīng)成功.");
//清空 為當(dāng)前連接做準(zhǔn)備? ??
self.receiveData.length=0;
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{? ? NSLog(@"已經(jīng)接收到了數(shù)據(jù).");? ??
//追加接收到的數(shù)據(jù)? ??
[self.receiveData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{? ??
NSLog(@"接收數(shù)據(jù)已經(jīng)完成.");?
/*? ? ? 對(duì)服務(wù)器獲取的數(shù)據(jù)receiveData進(jìn)行相應(yīng)的處理;? */
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{? ? NSLog(@"連接失敗.");
}
二、POST方法
1.同步post方法:
//1.創(chuàng)建一個(gè)web路徑? ??
NSString? *webPath=@""; ??
webPath = [webPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];? ? NSURL *url=[NSURL URLWithString:webPath];
//2.建立一個(gè)帶協(xié)議緩存類型的請(qǐng)求 (使用NSMutableURLRequest,是post方法的關(guān)鍵)? ? NSMutableURLRequest? *request=[NSMutableURLRequest requestWithURL:url cachePolicy:(NSURLRequestUseProtocolCachePolicy) timeoutInterval:10];? ? ? ? //3.設(shè)置表單提交的方法(默認(rèn)為get)? ? [request setHTTPMethod: @"post"];
//4.設(shè)置要提交的參數(shù)? ? NSString? *args=[NSString stringWithFormat:@"uname=%@upas=%@btn=login",uname,upas];? ? [request setHTTPBody: [args dataUsingEncoding:NSUTF8StringEncoding]];
NSData *recvData=[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];? ? if(recvData!=nil)? ? {
/*
對(duì)服務(wù)器獲取的數(shù)據(jù)recvData進(jìn)行相應(yīng)的處理
*/
}
else
{
NSLog(@"連接失敗,請(qǐng)重試!");
}
2.post方法的異步與同步的區(qū)別在于使用NSURLConnectionDataDelegate委托協(xié)議,指定代理.
這一點(diǎn)與get方法一致,所以就不進(jìn)行長(zhǎng)篇幅的演示了。
以上就是關(guān)于部分網(wǎng)絡(luò)同步異步請(qǐng)求,get、post請(qǐng)求方法的演示,由于UI控件還有其他的處理沒(méi)有附上,具體的讀者可以進(jìn)行相應(yīng)細(xì)節(jié)的調(diào)整,進(jìn)行完整的網(wǎng)絡(luò)請(qǐng)求項(xiàng)目開(kāi)發(fā)。
由于iOS開(kāi)始,引入了新的網(wǎng)絡(luò)接口NSURLSession,而在iOS9中NSURLConnection被宣布棄用,因此關(guān)于NSURLSession發(fā)送GET和POST請(qǐng)求的資料部分,有興趣的可以參考:
iOS開(kāi)發(fā) GET、POST請(qǐng)求方法(NSURLSession篇)
? by:啊左~
[img]按照我的理解
1,get請(qǐng)求的參數(shù)會(huì)被放在url中,而post的參數(shù)會(huì)被放在body中。
2,因?yàn)樯厦娴木壒?,所以說(shuō)get比post略顯不安全,因?yàn)楸热绲卿浢艽a用get的方式的話,都是明文顯示在url中的,會(huì)被瀏覽器緩存。
3,一般用get來(lái)進(jìn)行獲取數(shù)據(jù),因?yàn)橛芯彺妫钥梢越档头?wù)器的壓力;而post一般用來(lái)進(jìn)行操作數(shù)據(jù),如增刪改。
4,get由于url或者瀏覽器長(zhǎng)度限制,一般參數(shù)不能超過(guò)1k,而post沒(méi)有長(zhǎng)度限制,所以進(jìn)行大文件上傳的話用post。
參考文章:
從表面的意思看get 和 post的區(qū)別get就是獲取數(shù)據(jù),post就是發(fā)送數(shù)據(jù)。這個(gè)是誤區(qū)。其實(shí)兩者都可以的,在IOS向服務(wù)器發(fā)送請(qǐng)求里面可以帶參數(shù)。
那么這些誤區(qū)是怎么出現(xiàn)的呢?先看看一下對(duì)http的解釋
一般在瀏覽器中輸入網(wǎng)址訪問(wèn)資源都是通過(guò)GET方式;在FORM提交中,可以通過(guò)Method指定提交方式為GET或者POST,默認(rèn)為GET提交
Http定義了與服務(wù)器交互的不同方法,最基本的方法有4種,分別是GET,POST,PUT,DELETE
URL全稱是資源描述符,我們可以這樣認(rèn)為:一個(gè)URL地址,它用于描述一個(gè)網(wǎng)絡(luò)上的資源,而HTTP中的GET,POST,PUT,DELETE就對(duì)應(yīng)著對(duì)這個(gè)資源的查 ,改 ,增 ,刪 4個(gè)操作。到這里,大家應(yīng)該有個(gè)大概的了解了,GET一般用于獲取/查詢 資源信息,而POST一般用于更新 資源信息(個(gè)人認(rèn)為這是GET和POST的本質(zhì)區(qū)別,也是協(xié)議設(shè)計(jì)者的本意,其它區(qū)別都是具體表現(xiàn)形式的差異 )。
再進(jìn)一步了解下他們兩個(gè)的區(qū)別:
1. GET使用URL或Cookie傳參。而POST將數(shù)據(jù)放在BODY中。
2. GET的URL會(huì)有長(zhǎng)度上的限制,則POST的數(shù)據(jù)則可以非常大。
3. POST比GET安全,因?yàn)閿?shù)據(jù)在地址欄上不可見(jiàn)。
這些也是有點(diǎn)誤區(qū)的,就像同步請(qǐng)求一定的慢嗎?
GET和POST與數(shù)據(jù)如何傳遞沒(méi)有關(guān)系?
GET和POST是由HTTP協(xié)議定義的。在HTTP協(xié)議中,Method和Data(URL, Body, Header)是正交的兩個(gè)概念,也就是說(shuō),使用哪個(gè)Method與應(yīng)用層的數(shù)據(jù)如何傳輸是沒(méi)有相互關(guān)系的。
HTTP沒(méi)有要求,如果Method是POST數(shù)據(jù)就要放在BODY中。也沒(méi)有要求,如果Method是GET,數(shù)據(jù)(參數(shù))就一定要放在URL中而不能放在BODY中。
那么,網(wǎng)上流傳甚廣的這個(gè)說(shuō)法是從何而來(lái)的呢?我在HTML標(biāo)準(zhǔn)中,找到了相似的描述。這和網(wǎng)上流傳的說(shuō)法一致。但是這只是HTML標(biāo)準(zhǔn)對(duì)HTTP協(xié)議的用法的約定。怎么能當(dāng)成GET和POST的區(qū)別呢?
而且,現(xiàn)代的Web Server都是支持GET中包含BODY這樣的請(qǐng)求。雖然這種請(qǐng)求不可能從瀏覽器發(fā)出,但是現(xiàn)在的Web Server又不是只給瀏覽器用,已經(jīng)完全地超出了HTML服務(wù)器的范疇了。
HTTP協(xié)議對(duì)GET和POST都沒(méi)有對(duì)長(zhǎng)度的限制?
HTTP協(xié)議明確地指出了,HTTP頭和Body都沒(méi)有長(zhǎng)度的要求。而對(duì)于URL長(zhǎng)度上的限制,有兩方面的原因造成:
1. 瀏覽器。據(jù)說(shuō)早期的瀏覽器會(huì)對(duì)URL長(zhǎng)度做限制。據(jù)說(shuō)IE對(duì)URL長(zhǎng)度會(huì)限制在2048個(gè)字符內(nèi)(流傳很廣,而且無(wú)數(shù)同事都表示認(rèn)同)。但我自己試了一下,我構(gòu)造了90K的URL通過(guò)IE9訪問(wèn)live.com,是正常的。網(wǎng)上的東西,哪怕是Wikipedia上的,也不能信。
2. 服務(wù)器。URL長(zhǎng)了,對(duì)服務(wù)器處理也是一種負(fù)擔(dān)。原本一個(gè)會(huì)話就沒(méi)有多少數(shù)據(jù),現(xiàn)在如果有人惡意地構(gòu)造幾個(gè)幾M大小的URL,并不停地訪問(wèn)你的服務(wù)器。服務(wù)器的最大并發(fā)數(shù)顯然會(huì)下降。另一種攻擊方式是,把告訴服務(wù)器Content-Length是一個(gè)很大的數(shù),然后只給服務(wù)器發(fā)一點(diǎn)兒數(shù)據(jù),嘿嘿,服務(wù)器你就傻等著去吧。哪怕你有超時(shí)設(shè)置,這種故意的次次訪問(wèn)超時(shí)也能讓服務(wù)器吃不了兜著走。有鑒于此,多數(shù)服務(wù)器出于安全啦、穩(wěn)定啦方面的考慮,會(huì)給URL長(zhǎng)度加限制。但是這個(gè)限制是針對(duì)所有HTTP請(qǐng)求的,與GET、POST沒(méi)有關(guān)系。
這個(gè)貌似聽(tīng)著對(duì)點(diǎn)吧。
3.對(duì)于安全不安全講。
get:
.所謂安全的意味著該操作用于獲取信息而非修改信息。換句話說(shuō),GET請(qǐng)求一般不應(yīng)產(chǎn)生副作用。就是說(shuō),它僅僅是獲取資源信息,就像數(shù)據(jù)庫(kù)查詢一樣,不會(huì)修改,增加數(shù)據(jù),不會(huì)影響資源的狀態(tài)。
* 注意:這里安全的含義僅僅是指是非修改信息。
POST的安全性要比GET的安全性高。注意:這里所說(shuō)的安全性和上面GET提到的“安全”不是同個(gè)概念。上面“安全”的含義僅僅是不作數(shù)據(jù)修改,而這里安全的含義是真正的Security的含義,比如:通過(guò)GET提交數(shù)據(jù),用戶名和密碼將明文出現(xiàn)在URL上,因?yàn)?1)登錄頁(yè)面有可能被瀏覽器緩存, (2)其他人查看瀏覽器的歷史紀(jì)錄,那么別人就可以拿到你的賬號(hào)和密碼了,除此之外,使用GET提交數(shù)據(jù)還可能會(huì)造成Cross-site request forgery攻擊 .