Cookie簡介

HULK一線技術雜談發表於2019-05-14

級別: ★☆☆☆☆
標籤:「iOS 」「Cookie簡介」「AFN Cookie」「NSURLSession Cookie」
作者: WYW
審校: QiShare團隊


前言 筆者最近看了部分關於Cookie的內容,寫了如下文字,給大家分享下。

Cookie是什麼

  • Cookie

Cookie,有時也用其複數形式Cookies,指某些網站為了辨別使用者身份、進行session跟蹤而儲存在使用者本地終端上的資料(通常經過加密)。360百科 Cookie

插曲Session

  • Session

由於HTTP協議是無狀態的協議,所以當服務端需要記錄使用者狀態時,就需要用某種機制來識別具體的使用者,這個機制就是Session。

Cookie有什麼用

筆者以簡書顯示內容為繁體還是簡體為例,來介紹Cookie的用處:

(1)當我們使用瀏覽器訪問jianshu.com時,簡書服務端不知道瀏覽器的資訊,預設情況下,瀏覽器顯示內容為“簡體”;

(2)當我們設定瀏覽器顯示內容為“繁體”時,瀏覽器將顯示繁體內容;

(3)當我們關閉瀏覽器,再重新開啟瀏覽器,發現簡書的顯示內容仍然會是繁體;筆者認為原因是簡書服務端可能給瀏覽器做了一個唯一標識的記錄,放置到自己的Session中,當瀏覽器重啟後,再去服務端請求簡書內容,發現當前瀏覽器需要顯示為繁體,便下發了繁體顯示內容。

(4)如果沒有使用Cookie,因為HTTP協議是無狀態的,那麼我們設定的顯示內容為繁體或者簡體後,當我們開啟新的頁面或關閉瀏覽器重新開啟的時候,之前設定的顯示繁體或者簡體便不存在了。

Cookie的型別

摘自HTTP權威指南

籠統地說,Cookie分為2類: 會話Cookie持久Cookie

會話Cookie是一種臨時Cookie,它記錄使用者訪問長點是的設定和偏好。使用者退出瀏覽器時,會話Cookie就被刪除了。

持久Cookie的生存時間更長一些,他們儲存在硬碟上,瀏覽器退出,計算機重啟時,他們仍然存在。通常用持久Cookie維護某個使用者會週期性訪問的站點的配置檔案或登入名。

會話Cookie和持久Cookie之間的唯一區別就是他們的過期時間。 沒有指定Expires(過期時間)時,預設為會話Cookie。

以簡書為例: 看下簡書的會話Cookie和持久Cookie:

持久Cookie 會話Cookie

上圖表明: jianshu.com的cookies

持久Cookie:

  • expires 過期時間為2018年4月9日星期二 Tue,09 Apr 2019 13:31:57 -0000
    • 筆者猜測這個值表示的意思是當前的某個時間減去0000,以達到作為持久Cookie的目的
  • domain 為.jianshu.com
  • Path 為 /
  • Secure為YES
  • Http only 為true;

會話Cookie:

  • local:zh-CN 顯示為簡體;

包括會話Cookie,筆者以為關閉瀏覽器後會話Cookie就會消失,不過筆者的如下測試結果,不確定算不算是會話Cookie消失的一種體現。首次啟動瀏覽器顯示的會話Cookie為:

local:zh-CN;

path:/;

default_font:font1;

設定過繁體的情況:

local:zh-TW;

path:/;

default_font:font1;

然後重新整理jianshu.com,顯示內容,就只會顯示

local:zh-CN

或是

local:zh-TW

不確定這個算不算是會話Cookie在關閉瀏覽器後,就消失了。讀者也可以自己測試一下。有做服務端的同學知道的話,敬請告知。

Cookie的工作流程

筆者仍以瀏覽器開啟簡書顯示內容字型為“簡體”或是“繁體”為例闡述Cookie的工作流程。

(1)當我們使用瀏覽器首次訪問jianshu.com時,簡書服務端不知道瀏覽器的資訊,預設情況下,瀏覽器顯示內容為“簡體”。服務端對瀏覽器建立一個Session;

(2)當我們設定瀏覽器顯示內容為“繁體”時,會通過Cookie的方式設定local為zh-TW,給服務端傳送請求,並且得到的響應會是設定瀏覽器的顯示內容為“繁體”,服務端同事會更新Session中的資訊為zh-TW(繁體);

(3)當我們關閉瀏覽器,會話消失的情況下,然後我們再重新開啟瀏覽器,發現簡書的顯示內容仍然會是繁體,筆者認為這個是因為簡書服務端Session儲存著瀏覽器應該顯示字型,(比如服務端儲存著瀏覽器的某個唯一的id,然後當重新開啟瀏覽器,對服務端做請求時,服務端根據之前的Session下發繁體內容)。

Cookie的屬性

  • Domain(域):Cookie的域;瀏覽器只向指定域中的伺服器主機名傳送Cookie,這樣伺服器就將Cookie限制在了特定的域中。jianshu.com域就與jianshu1.jianshu.com和jianshu1.jianshu2.jianshu.com相匹配,但與js.com就不匹配了。
  • Path(路徑):通過這個屬性可以為伺服器上特定的文件分配Cookie,如果Path屬性是一個URL路徑字首,就可以附加一個Cookie,路徑/foo,與/foobar和foo/bar.html相匹配,路徑"/"與域名中所有的內容都匹配。
  • Secure(安全):是否只有在HTTP使用SSL連線時才傳送這個Cookie;
  • expires(過期):從格林尼治標準時間1970年1月1日00:00:00開始的過期秒數;
  • name(名字): Cookie變數的名字;
  • value(值):Cookie變數的值;

iOS 中的NSHTTPCookie

常用屬性:

  • NSHTTPCookieDomain domain:cookie的域;
  • NSHTTPCookiePath path: Cookie的path;
  • NSHTTPCookiePort portList:Cookie的埠列表;
  • NSHTTPCookieName name:Cookie的名字;
  • NSHTTPCookieValue value:Cookie的值;
  • NSHTTPCookieVersion version: Cookie的版本;
  • NSHTTPCookieExpires expireDate:Cookie的過期時間;
  • NSHTTPCookieDiscard sessionOnly:一個布林值,表示cookie是否應該在會話結束的時候被丟棄(不管過期日期);
  • HTTPOnly:指定客戶端不要與JavaScript應用共享Cookie,以防止跨站指令碼攻擊;
  • NSHTTPCookieSecure secure:指定Cookie只會用在HTTPS連線而非HTTP連線;
  • properties:Cookie的屬性;
  • NSHTTPCookiePropertyKey:定義cookie屬性字典中支援的常量;
  • NSHTTPCookieComment comment:Cookie的說明文字
  • NSHTTPCookieCommentURL commentURL:cookie的說明URL;
  • NSHTTPCookieAcceptPolicy:Cookie的訪問許可權,NSHTTPCookie由NSHTTPCookieStorage管理。
    • NSHTTPCookieAcceptPolicyAlways:儲存所有的cookie;
    • NSHTTPCookieAcceptPolicyNever:不會儲存cookie;
    • NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:只儲存域值和請求域相匹配的Cookie;

iOS 網路請求使用Cookie

客戶端的請求頭裡邊的cookie的header,key為"cookie"

服務端響應客戶端的時候,響應頭中的cookie的header,key為"set-cookie"

  • 網路請求使用AFN攜帶Cookie 測試AFN網路請求攜帶Cookie,筆者使用的是訪問juejin.im的時候攜帶Cookie,效果如下圖:
    AFNJuejinCookie.png

相關程式碼如下:

    NSString *urlString = @"https://juejin.im";
    AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];
    sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [sessionManager.requestSerializer setValue:@"QiShareNameAFN=QiShareValueAFN;QiShareTokenAFN=QiShareTokenValueAFN" forHTTPHeaderField:@"cookie"];
    [sessionManager GET:urlString parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
    }];
複製程式碼

當需要設定多個cookie值的時候,使用cookieKey1=cookieValue1;cookieKey2=cookieValue2;的方式,使用分號分隔開每一對cookieKey及Value。

  • 網路請求使用NSURLSession攜帶Cookie

測試NSURLSession網路請求攜帶Cookie,筆者使用的是訪問jianshu.com的時候攜帶Cookie,效果如下圖:

NSURLSessionJianshuCookie.png

相關程式碼如下:

    NSURL *url = [NSURL URLWithString:@"https://www.jianshu.com"];
    NSMutableURLRequest *mRequest = [NSMutableURLRequest requestWithURL:url];
    mRequest.HTTPMethod = @"GET";
    [mRequest setValue:@"QiShareName=QiShareValue;QiShareToken=QiShareTokenValue" forHTTPHeaderField:@"cookie"];
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:mRequest completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
    }];
    [dataTask resume];
複製程式碼

Demo:

更多相關內容,可檢視 QiNetwork

參考學習網址


小編微信:可加並拉入《QiShare技術交流群》。

Cookie簡介

關注我們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公眾號)

推薦文章:
iOS 圖示&啟動圖生成器(一)
演算法小專欄:“D&C思想”與“快速排序”
iOS 避免常見崩潰(二)
演算法小專欄:選擇排序
iOS Runloop(一)
iOS 常用除錯方法:LLDB命令
iOS 常用除錯方法:斷點
iOS 常用除錯方法:靜態分析
奇舞週刊

相關文章