你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 【IOS學習】網絡請求中的cookie

【IOS學習】網絡請求中的cookie

編輯:IOS開發綜合

服務端代碼


    //設置cookie
	function cookie(req,res){
		//打印客戶端的cookie
		console.log("client cookie:"+req.headers.cookie);

		var today = new Date();
		var time = today.getTime() + 60*1000;
		var time2 = new Date(time);
		var timeObj = time2.toGMTString();

        //給f的值添加了一個過期時間的參數
	    res.setHeader("Set-Cookie", ['d=001;maxAge=10*1000', 'e=1112', 'f=2222;Expires='+timeObj]);

		var msg = { "status":1,"msg":"succeed"}
		res.write(JSON.stringify(msg));
		res.end();
	}

這段代碼主要有2個地方需要注意,一是服務端設置cookie並返回到客戶端,一個是服務端獲取客戶端上傳的cookie

服務端設置cookie

服務端設置主要是通過在相應頭中設置Set-Cookie,可以使用response.writeHead或是response.setHeader方法設置

cookie的設置的一般格式:

單個

    Set-Cookie:
            cookieName=cookieValue;
            [expires=]
            [;domain=]
            [;path=]
            [;secure=]
            [;httpOnly=]

多個

    Set-Cookie:'[cookie1,cookie2];

參數說明:

1、expires:指定過期時間,以GMT格式表示的時間字符串,如方法一個的“timeObj”。
2、maxAge:指定過期時間,同expires(expires和maxAge選兩者其一設值即可)。和expires不同之處在於,maxAge值的單位為毫秒(見方法二中的maxAge:10*1000,即為10秒)。maxAge值可以是正數和負數。正數表示當前COOKIE存活的時間。負數表示當前COOKIE只是隨著浏覽器存儲在客戶端的內存裡,只要關閉浏覽器,此COOKIE就馬上消失。默認值為-1。
3、domain:指定可訪問COOKIE的主機名。主機名是指同一個域名下的不同主機。如:www.google.com和gmail.google.com是在兩個不同的主機上,即兩個不同的主機名。默認情況下,一個主機中創建的COOKIE在另一個主機下是不能被訪問,但可以通過domain參數來實現對其的控制,即所謂的跨子域。以google為例,要實現跨主機(跨子域)訪問,寫法如下:domain=.google.com,這樣就實現了所有google.com下的主機都可以訪問此COOKIE。(本機環境上設置此值時,COOKIE無法查看。)
4、path:指定可訪問此COOKIE的目錄。如:path=/default  表示當前COOKIE僅能在 default 目錄下使用。默認值為“/”,即根目錄下的所有目錄皆可以訪問。
5、secure:當設為true時,表示創建的COOKIE會以安全的形式向服務器傳輸,即只能在HTTPS連接中被浏覽器傳遞到服務器端進行會話驗證;若是HTTP連接則不會傳遞該信息,所以不會被竊取到COOKIE裡的具體內容。同理,在客戶端,我們也無法使用document.cookie找到被設置了secure=true的cookie健值對。secure屬性是防止信息在傳遞的過程中被監聽捕獲後信息洩漏,httpOnly屬性的目的是防止程序獲取COOKIE後進行攻擊(XSS)。我們可以把secure=true看成比httpOnly=true是更嚴格的訪問控制。
6、httpOnly:是微軟對COOKIE做的擴展。如果在COOKIE中設置了“httpOnly”屬性,則通過程序(JS腳本、applet等)將無法讀取到COOKIE信息,防止XSS攻擊產生。

服務端設置cookie的例子:

//例子1
res.setHeader("Set-Cookie", ['a=001', 'b=1112', 'c=2222']);

//例子2 設置過期時間
var today = new Date();
var time = today.getTime() + 60*1000;
var time2 = new Date(time);
var timeObj = time2.toGMTString();
 res.setHeader("Set-Cookie", ['d=001', 'e=1112', 'f=2222;Expires='+timeObj,]);

//例子3:
res.writeHead(200,{
    'Content-type':'text/json',
    "Set-Cookie":['a=001', 'b=1112', 'c=2222']
});

服務端獲取客戶端cookie

//打印客戶端的cookie
console.log("client cookie:"+req.headers.cookie);

服務端刪除或修改cookie

刪除和修改cookie本質都是一樣的,把原來存在的cookie設為空值,就是刪除,設為其他的值就是修改,服務端也有封裝好的cookie庫, 我們這裡的方法都是最底層的htpp模塊的方法。

客戶端iOS 操作cookie


獲取服務端返回的cookie


    //獲取cookie
    NSDictionary *headers = [((NSHTTPURLResponse *)resp) allHeaderFields];
    NSLog(@"headers:%@",headers);
    NSDictionary *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:headers forURL:[NSURL URLWithString:@"http://localhost/"]];

    for (NSHTTPCookie *cookie in cookies) {
        NSLog(@"cookie:%@",cookie);
    }

服務端返回的cookie在響應頭中,請求上節服務端代碼設置cookie的那個路徑:http://localhost:8001/cookie 後打印的結果如下:

2016-02-13 18:04:08.611 network-demo[20302:1737476] ====請求開始====
2016-02-13 18:04:08.611 network-demo[20302:1737476] {
    msg = succeed;
    status = 1;
}
2016-02-13 18:04:08.611 network-demo[20302:1737476] ====請求結束====
2016-02-13 18:04:08.611 network-demo[20302:1737476] headers:{
    Connection = "keep-alive";
    Date = "Sat, 13 Feb 2016 10:04:08 GMT";
    "Set-Cookie" = "d=001;maxAge=10*1000, e=1112, f=2222;Expires=Sat, 13 Feb 2016 10:05:08 GMT";
    "Transfer-Encoding" = Identity;
}
2016-02-13 18:04:08.617 network-demo[20302:1737476] cookie:
2016-02-13 18:04:08.617 network-demo[20302:1737476] cookie:
2016-02-13 18:04:08.617 network-demo[20302:1737476] cookie:

可以看到服務端獲取了3個cookie,key分別是d,e,f,其中f設置了cookie的過期時間。

客戶端cookie會在每次請求中把cookie自動加載到請求頭中發送給服務端, 我們已經收到相應的cookie後,再次請求服務端另一個沒有設置cookie的url,看看服務端打印出客戶端請求頭中的cookie

{ host: 'localhost:8001',
  accept: '*/*',
  cookie: 'd=001; e=1112',
  'user-agent': 'network-demo/1 CFNetwork/758.0.2 Darwin/14.5.0',
  'accept-language': 'en-us',
  'accept-encoding': 'gzip, deflate',
  connection: 'keep-alive' }
/
client cookie:d=001; e=1112

可以看到請求頭中獲取到了cookie:client cookie:d=001; e=1112。 但是這裡有個問題,我少了一個key為f的cookie,那是因為f的cookie已經過期了。再看之前iOS模擬器打印的過期時間和服務返回的時間有8小時時差,這個應該是 服務端的時間制式和客戶端的制式不同導致的吧,已經搞mongodb的時候也遇到過,這裡不用糾結這些小問題了,反正就是過期了。

獲取客戶端存儲的cookie

通過NSHTTPCookieStorage的單例類就可以獲取到之前服務端的cookie

//獲取本地cookie
NSHTTPCookieStorage *httpCookiesStorage =  [NSHTTPCookieStorage sharedHTTPCookieStorage];
NSDictionary *cookies = [httpCookiesStorage cookiesForURL:[NSURL URLWithString:@"http://localhost/"]];
for (NSHTTPCookie *cookie in cookies) {
    NSLog(@"cookie:%@",cookie);
}

客戶端設置本地cookie


//客戶端設置cookie
-(void)clientSetCookie{

    NSDictionary *prop1 = [NSDictionary dictionaryWithObjectsAndKeys:
                           @"a",NSHTTPCookieName,
                           @"aaa",NSHTTPCookieValue,
                           @"/",NSHTTPCookiePath,
                           [NSURL URLWithString:@"http://localhost/"],NSHTTPCookieOriginURL,
                           [NSDate dateWithTimeIntervalSinceNow:60],NSHTTPCookieExpires,
                           nil];

    NSDictionary *prop2 = [NSDictionary dictionaryWithObjectsAndKeys:
                           @"b",NSHTTPCookieName,
                           @"bbb",NSHTTPCookieValue,
                           @"/",NSHTTPCookiePath,
                           [NSURL URLWithString:@"http://localhost/"],NSHTTPCookieOriginURL,
                           [NSDate dateWithTimeIntervalSinceNow:60],NSHTTPCookieExpires,
                           nil];

    NSHTTPCookie *cookie1 = [NSHTTPCookie cookieWithProperties:prop1];
    NSHTTPCookie *cookie2 = [NSHTTPCookie cookieWithProperties:prop2];

    //單個設置
//    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie1];
//    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie2];

    //批量設置
    NSArray *cookies = @[cookie1,cookie2];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookies:cookies forURL:[NSURL URLWithString:@"http://localhost/"] mainDocumentURL:nil];

    NSLog(@"設置完成");
}

說明: - 設置好了之後,下次請求url時會自動帶入cookie中的數據 -[NSDate dateWithTimeIntervalSinceNow:60]是設置1分鐘後超時 - 可以一個個設置也可以使用setCookies批量設置 - mainDocumentURL: The URL of the main HTML document for the top-level frame, if known. Can be nil. This URL is used to determine if the cookie should be accepted if the cookie accept policy is NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain

刪除cookie

- (void)deleteCookie:(NSHTTPCookie *)cookie;
- (void)removeCookiesSinceDate:(NSDate *)date NS_AVAILABLE(10_10, 8_0);

我們來示范如何刪除cookie

    #pragma mark -客戶端刪除cookie
    //根據url和name刪除cookie
    -(void)deleteCookie:(NSString *)cookieName url:(NSURL *)url{
        //根據url找到所屬的cookie集合
        NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookiesForURL:url];
        for (NSHTTPCookie *cookie in cookies) {
            if([cookie.name isEqualToString:cookieName]){
                [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
                NSLog(@"刪除cookie:%@",cookieName);
            }
        }
    }
    //刪除全部cookies
    -(void)deleteCookies{
        for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage]cookies]) {
            [[NSHTTPCookieStorage sharedHTTPCookieStorage] deleteCookie:cookie];
        }
        NSLog(@"刪除完成");
    }

cookie的本地緩存策略

//設置cookie本地緩存策略
//NSHTTPCookieAcceptPolicyAlways:保存所有cookie,這個是默認值
//NSHTTPCookieAcceptPolicyNever:不保存任何響應頭中的cookie
//NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只保存域請求匹配的cookie

我們測試一下效果:[[NSHTTPCookieStorage sharedHTTPCookieStorage]setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyNever];

這樣設置之後,調用demo中的客戶端設置cookie,在調用從服務端獲取cookie,最後調用打印客戶端cookie,查看日志:


我們可以看到,客戶端沒有打印任何cookie,因為設置的策略為:NSHTTPCookieAcceptPolicyNever

我們在修改為NSHTTPCookieAcceptPolicyAlways 或是 NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain,再次測試一次,可以看到,服務端和客戶端設置的cookie都會打印出來。這兩個選項會針對不同域名返回的cookie做選擇性保存。

2016-02-14 00:59:47.030 network-demo[21191:1810897] cookie:
2016-02-14 00:59:47.030 network-demo[21191:1810897] cookie:
2016-02-14 00:59:47.030 network-demo[21191:1810897] cookie:
2016-02-14 00:59:47.031 network-demo[21191:1810897] cookie:
2016-02-14 00:59:47.031 network-demo[21191:1810897] cookie:

使用cookie的注意點


Cookie的性能影響

由於Cookie的實現機制,除非Cookie過期,否則浏覽器每次請求都會向服務器發送Cookie,一旦Cookie設置過多,會導致請求報頭過大,造成帶寬的浪費。因此,對Cookie的性能優化也是值得關注的一個問題。如何進行性能優化?

  • 減小Cookie的大小
  • 為不需要Cookie的組件換個域名,以減少無效Cookie的傳輸
  • 減少DNS查詢
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved