用AFNetworking訪問接口時附帶多個cookie

問題:

最近在做一個登錄相關(guān)的迭代開發(fā)時唠亚,后臺對cookie的支持升級蚪战,變的更加“標準”牵现,即:由 原來附在請求頭的set-cookie是只對應一個value 變成 對應多個value。要求前段和移動端進行適配接收邀桑,保存新的set-cookie瞎疼,并且在其他接口上傳該結(jié)構(gòu)的cookie。

分析:

問題分為兩大部分壁畸,一是接收并解析保存贼急,二是訪問其他接口附帶上傳茅茂。因為接收解析相對簡單,蘋果有專用的NSHTTPCookie類支持太抓,網(wǎng)上也有很多資料空闲,本文就不多贅述,僅僅帶一下走敌。關(guān)于第二點进副,筆者百度了很久都沒有合適的解決方案,最后還是在和后臺的聯(lián)調(diào)中摸索而出悔常,故寫本文以作記錄影斑。

一、接收机打,解析矫户,保存

這個比較簡單,無論是AFNetworking還是NSHTTPCookie類都簡潔易用残邀,直接上代碼:

//從AFNetworking的post請求中獲得請求頭皆辽,該頭的格式為NSDictionary
//其中operation是指AFHTTPRequestOperation *operation
NSDictionary *allHeaderFieldDict = [operation.response allHeaderFields];

//用NSHTTPCookie直接將請求頭中的setCookie轉(zhuǎn)成鍵值對形式的數(shù)組,后面用到芥挣。另外說下NSHTTPCookie會自動過濾非setCookie的鍵值對驱闷。
NSArray *cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:allHeaderFieldDict forURL:[NSURL URLWithString:url]];

//用字符串的形式拿到set-Cookie對應的value
NSString *setCookie = [allHeaderFieldDict objectForKey:@"Set-Cookie"];      

這里說下,后臺給我的set-Cookie是多個的空免,多個是個什么概念呢?后臺給我了一張圖空另,便于理解
圖1.多個set-Cookie.png

是不是感到很疑惑,如果是key-value的形式蹋砚,眾所周知一個Map(或者說是字典)里扼菠,key是唯一的,不可能是一個“set-Cookie”作為key對應多個value坝咐。驗證這一點我們可以打印下上面代碼中的setCookie字符串循榆,看取到了什么?
圖2.這是setCookie字符串的打印結(jié)果
為了方便閱讀我把字符串粘出來并對其一下墨坚,*為我手動打碼
id=*****; domain=.*******.com; expires=Fri, 08-Dec-2017 05:48:20 GMT; path=/,
 mobile=***********; domain=.*******.com; expires=Fri, 08-Dec-2017 05:48:20 GMT; path=/,
 timestart=2017/11/23 13:48:20; domain=.*******.com; expires=Fri, 08-Dec-2017 05:48:20 GMT; path=/,
 timespan=15; domain=.*******.com; expires=Fri, 08-Dec-2017 05:48:20 GMT; path=/,
 identifier=85EF24DAF969423EA129C6A15863936B; domain=.*******.com; expires=Fri, 08-Dec-2017 05:48:20 GMT; path=/,
 token=ae9721de81f3b6c336ccd94abae9c698; domain=.*******.com; expires=Fri, 08-Dec-2017 05:48:20 GMT; path=/

這里要著重說明三點秧饮,這三點在上傳時很重要。

  • OC中key-value是標準的一對一泽篮,所以后臺發(fā)的圖1那種形式被轉(zhuǎn)成了圖2的樣子盗尸。其vaule是包含上圖所有value的字符串,這個字符串的格式很重要_淙琛U窭汀!
  • 我進行了換行操作油狂,分成了6行,注意從第二行開始位置錯了一個空格。這不是我要逼死強迫癥的操作专筷,而是原字符串在第一行結(jié)尾和第二行開頭中間本來就有一個空格弱贼。我實在想不出怎么體現(xiàn)這個空格就出此下策。要是還不信你就仔細看圖2里面是不是真的有空格磷蛹。為什么說這么多廢話強調(diào)一個空格吮旅,因為格式很重要!N犊取庇勃!
  • 還是格式問題,每個;和,的后面空格槽驶,仔細觀察责嚷。格式很重要!5囝怼罕拂!

看完費勁的字符串,我們再來看下蘋果提供的NSHTTPCookie類拿到的優(yōu)雅的cookie結(jié)構(gòu)全陨,遍歷cookies數(shù)組打印如下:
圖3.NSHTTPCookie類解析的cookies數(shù)組打印截圖

太長了爆班,截不下,不過不影響理解辱姨,從上圖我們可以方便的看出圖1的格式柿菩。而且這中方法比較好的點在于,不在乎后面的一個key對應了多少個value雨涛,有幾個value數(shù)組就有幾個元素碗旅。像我公司原來的后臺就只有1個value還能用字符串去取,現(xiàn)在改成多個了镜悉,顯然這個方法更利于理解祟辟。
接收到,解析完侣肄,儲存的話旧困,我相信你肯定會存字符串,也肯定會存數(shù)組吧稼锅。

二吼具、訪問時上傳

一般的cookie上傳如下:

//manager即[AFHTTPRequestOperationManager manager];返回的單例
//cookStr即cookie
[manager.requestSerializer setValue:cookStr forHTTPHeaderField:@"Cookie"];

事實上AFNetworking只有這一個方法將一個鍵值對加入請求頭,同樣value自然也必須是字符串矩距。
對于我程序中遇到的多個cookie

  • 我考慮過將幾個鍵值對變成字典然后用上面的方法放入請求頭拗盒,但顯然字典不符合value必須是String的設定。
  • 然后我有考慮將字典轉(zhuǎn)成JSONString放入value,但后臺拿到的是帶有轉(zhuǎn)義字符的字符串锥债,無法解析陡蝇。
  • 如果將cookie分別以自己的key(比如id,mobile,timestart等)分別加入HTTPHeaderField又不符合后臺的標準化需求痊臭。
  • 后臺反復強調(diào)將cookie以發(fā)送給我的方式返回,經(jīng)過再三調(diào)試和思考登夫,發(fā)現(xiàn)拿到的cookie其本質(zhì)是一個字符串广匙,但這個字符是有格式的!(所以說格式很重要D詹摺Q恢隆!)

最后經(jīng)過調(diào)試涣楷,返回了如下格式的字符串,*為手動打碼

NSString * cookStr = @"id=*****; mobile=***********; timestart=2017/11/23 13:48:20; timespan=15; identifier=85EF24DAF969423EA129C6A15863936B; token=ae9721de81f3b6c336ccd94abae9c698"

注意分唾,id前面與token最后面沒有空格,但每個;后面有一個空格狮斗。token字符串最后沒有;

[manager.requestSerializer setValue:cookStr forHTTPHeaderField:@"Cookie"];

將以上字符放入請求頭后绽乔,經(jīng)過請求后臺反饋可以解析返回的cookie。

長求總:

如果你的后臺需要在請求頭里返回一個包含若干個cookie的set-Cookie情龄,你可以按以下格式嘗試返回迄汛。務必切記字符串中哪里有空格哪里沒空格。

NSString *cookStr = @"key1=value1; key2=value2; key3=value3; key4=value4"
[manager.requestSerializer setValue:cookStr forHTTPHeaderField:@"Cookie"];

最后夾帶點私貨 /滑稽

  1. 這個是將圖2字符串處理成最后上傳的字符串的方法,按需自取
/**
  *  其中的需要傳入?yún)?shù)在本文第一段中有詳細代碼
  */
-(NSString *)quickLoginMakeCookieWithCookiesArray:(NSArray *)cookies withCookieString:(NSString *)setCookie {
    NSMutableArray *titleArray = [[NSMutableArray alloc] init];
    for (NSHTTPCookie *cookie in cookies) {
        [titleArray addObject:[NSString stringWithFormat:@"%@=",cookie.name]];
    }
    
    NSMutableString *lastString = [[NSMutableString alloc] init];
    for (NSString *str in titleArray) {
        NSRange tokenRange = [setCookie rangeOfString:str];
        NSInteger beginLoc = tokenRange.location+tokenRange.length;
        NSInteger count = 0;
        for (;;) {
            count++;
            NSString *emunStr = [setCookie substringWithRange:NSMakeRange(beginLoc++, 1)];
            if ([emunStr isEqualToString:@";"]) {
                break;
            }
        }
        NSString *valueString = [setCookie substringWithRange:NSMakeRange(tokenRange.location+tokenRange.length, --count)];
        NSString *resultString = [NSString stringWithFormat:@"%@%@",str,valueString];
        
        if ([str isEqualToString:@"id="]) {
            [lastString appendFormat:@"%@",resultString];
        }
        else {
            [lastString appendFormat:@"; %@",resultString];
        }
    }
    return lastString;
}

  1. 解決聯(lián)調(diào)中格式或者參數(shù)不對時候的一個小Tip骤视,一般來說后臺自己在開發(fā)完代碼后也會用瀏覽器插件/模擬器發(fā)起一個網(wǎng)絡請求來調(diào)試代碼鞍爱。當然這個東西也是可以打印參數(shù)的。如果搞不定你的發(fā)送參數(shù)的話可以讓他把參數(shù)打印出來給你专酗,你對比你發(fā)送的參數(shù)睹逃,就能找到問題的所在了。
  • 最后祷肯,若有錯誤沉填,懇請斧正。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末佑笋,一起剝皮案震驚了整個濱河市翼闹,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蒋纬,老刑警劉巖猎荠,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異蜀备,居然都是意外死亡关摇,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進店門碾阁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來输虱,“玉大人,你說我怎么就攤上這事脂凶∠芏茫” “怎么了愁茁?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長横堡。 經(jīng)常有香客問我埋市,道長冠桃,這世上最難降的妖魔是什么命贴? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮食听,結(jié)果婚禮上胸蛛,老公的妹妹穿的比我還像新娘。我一直安慰自己樱报,他們只是感情好葬项,可當我...
    茶點故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著迹蛤,像睡著了一般民珍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上盗飒,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天嚷量,我揣著相機與錄音,去河邊找鬼逆趣。 笑死蝶溶,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的宣渗。 我是一名探鬼主播抖所,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼痕囱!你這毒婦竟也來了田轧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤鞍恢,失蹤者是張志新(化名)和其女友劉穎傻粘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體有序,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡抹腿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了旭寿。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片警绩。...
    茶點故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖盅称,靈堂內(nèi)的尸體忽然破棺而出肩祥,到底是詐尸還是另有隱情后室,我是刑警寧澤,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布混狠,位于F島的核電站岸霹,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏将饺。R本人自食惡果不足惜贡避,卻給世界環(huán)境...
    茶點故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望予弧。 院中可真熱鬧刮吧,春花似錦、人聲如沸掖蛤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蚓庭。三九已至致讥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間器赞,已是汗流浹背垢袱。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拳魁,地道東北人惶桐。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像潘懊,于是被迫代替她去往敵國和親姚糊。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理授舟,服務發(fā)現(xiàn)救恨,斷路器,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • iOS網(wǎng)絡編程讀書筆記 Facade Tester客戶端門面模式的實例(被動版本化) 被動版本化释树,所以硬編碼URL...
    melouverrr閱讀 1,600評論 3 7
  • 第5章 引用類型(返回首頁) 本章內(nèi)容 使用對象 創(chuàng)建并操作數(shù)組 理解基本的JavaScript類型 使用基本類型...
    大學一百閱讀 3,212評論 0 4
  • 百分之九十九的失敗根源是懶肠槽!
    小磊陳讀閱讀 132評論 0 0
  • 如果把寫作比作一個工具,也就是一個工具類產(chǎn)品奢啥,這個工具是用于整理用戶的想法和思考秸仙,并將其變成可傳播的文字內(nèi)容,就像...
    武明Ray閱讀 137評論 0 0