WKWebView Cookie Issue

概述

WKWebView Cookie Issue主要包括:

Cookie丟失問題
Cookie同步延遲問題

Cookie丟失問題

使用過WKWebView的都會遇到請求沒有帶上登錄態(tài),頁面訪問失敗的情況。在UIWebView中發(fā)起的請求會自動帶上存儲于NSHTTPCookieStorage容器中的Cookie必指,因此,我們一般都會將登錄態(tài)存儲于NSHTTPCookieStorage中入录;而WKWebView發(fā)起的請求不會自動帶上存儲于NSHTTPCookieStorage容器中的Cookie,目前主流的解決方案是:

  1. loadRequest前佳镜,在request header中設(shè)置Cookie, 解決首個請求Cookie帶不上的問題僚稿;
WKWebView *webView = [WKWebView new];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://y.qq.com"]];
[request setValue:@"skey=MgYzJipDFA" forHTTPHeaderField:@"Cookie"];
[webView loadRequest:request]; 
  1. 通過document.cookie設(shè)置Cookie解決后續(xù)頁面Ajax、iframe等請求的Cookie問題蟀伸;
WKUserContentController *userContentController = [WKUserContentController new];
WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource: @"document.cookie = 'skey=MgYzJipDFA';" injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
[userContentController addUserScript:cookieScript];

這種方案在遇到302請求的時候有點(diǎn)捉襟見襯贫奠,比如:


第一個請求RequestA: www.a.com,我們通過在request header里帶上Cookie:skey=MgYzJipDFA解決該請求的Cookie問題,接著RequestA重定向到RequestB:www.b.com,這個時候RequestB就可能因?yàn)闆]有攜帶www.b.com域名的Cookie而失敗望蜡。更棘手的是這里RequestB:www.b.comRequestA:www.a.com其實(shí)是地址相同的同一個對象,也就是說RequestB會帶上我們在RequestA header里設(shè)置的Cookie:skey=MgYzJipDFA拷恨,這樣如果RequestA是重定向到第三方網(wǎng)站脖律,就可能導(dǎo)致Cookie信息泄漏問題。當(dāng)然腕侄,由于每一次頁面跳轉(zhuǎn)前都會調(diào)用回調(diào)函數(shù):

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler; 

可以在該回調(diào)函數(shù)里攔截跳轉(zhuǎn)請求小泉,在request header中帶上或擦除Cookie,確保Cookie字段信息和NSHTTPCookieStorage容器中的一致冕杠,并重新loadRequest微姊。不過這種方法依然解決不了頁面iframe跨域請求的Cookie問題,畢竟-[WKWebView loadRequest:]只適合加載mainFrame Request分预。

document.cookie不能垮域設(shè)置Cookie兢交,因此,document.cookie添加Cookie的邏輯可以簡單調(diào)整下:



通過-[WKUserScript addUserScript:]注入腳本A笼痹,A不再是執(zhí)行document.cookie設(shè)置Cookie,而是在documentStart的時候配喳,拋通知(webkit messageHandlers)給客戶端酪穿,客戶端收到通知后,從NSHTTPCookieStorage容器中取出window.location.href對應(yīng)的Cookie晴裹,并執(zhí)行document.cookie將Cookie注入被济。

Cookie同步問題

document.cookie或response set-Cookie設(shè)置的Cookie會先存儲在WKWebView Cookie緩存(這里WKWebView Cookie緩存的說法可能不是很準(zhǔn)確)中,然后再同步到NSHTTPCookieStorage容器中涧团,而同步過程有1~2s左右的延遲(setCookie有1.5s左右的延遲只磷,而document.cookie的延遲更高些,大概在2.0s左右)泌绣。通過document.cookie設(shè)置Cookie的時候钮追,如果沒有指定過期時間,則屬于Session Cookie, WKWebView不會將Session Cookie同步到NSHTTPCookieStorage中赞别,這點(diǎn)和UIWebView有點(diǎn)差異畏陕。WKWebView發(fā)起的請求會自動帶上緩存中的Cookie而不會自動帶上NSHTTPCookieStorage中的Cookie。

  1. set-Cookie

    - (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler;
    

    通過該回調(diào)函數(shù)可以獲取部分response header set-Cookie字段仿滔,將Cookie信息同步到NSHTTPCookieStorage中惠毁;

  2. document.cookie
    可以在javascript層hook document.cookie set method,不過目前發(fā)現(xiàn)只有IOS 10系統(tǒng)上能hook成功崎页;另一種做法是設(shè)置定時器鞠绰,檢查document.cookie是否有更新,如果有則拋通知給客戶端飒焦,客戶端將Cookie信息同步到NSHTTPCookieStorage中蜈膨;

  3. WKProcessPool
    通過讓所有WKWebView共享同一個WKProcessPool實(shí)例,可以實(shí)現(xiàn)多個WKWebView之間共享Cookie數(shù)據(jù)牺荠,尤其是Session Cookie;

相對完美的方案

前面兩個問題的討論都是建立在WKWebView不支持NSURLProtocol的基礎(chǔ)上翁巍,如果WKWbView支持NSURLProtocol:

  1. WKWebView請求將從Network Process轉(zhuǎn)發(fā)到App Process, 最后由Loading System用NSURLConnection發(fā)起請求;
  2. NSURLConnection發(fā)起的請求會自動帶上NSHTTPCookieStorage中的Cookie;
  3. NSURLConnection響應(yīng)的set-Cookie字段會自動存儲到NSHTTPCookieStorage中休雌;

綜合上面3點(diǎn)灶壶,WKWebView Cookie Issue就只剩下document.cookie的同步問題;

筆者對webkit2沒有特別深入的了解杈曲,如有表述錯誤歡迎指正疏虫!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末绽乔,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌治专,老刑警劉巖语婴,帶你破解...
    沈念sama閱讀 218,858評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件榜田,死亡現(xiàn)場離奇詭異填大,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評論 3 395
  • 文/潘曉璐 我一進(jìn)店門间唉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來绞灼,“玉大人,你說我怎么就攤上這事呈野〉桶” “怎么了?”我有些...
    開封第一講書人閱讀 165,282評論 0 356
  • 文/不壞的土叔 我叫張陵被冒,是天一觀的道長军掂。 經(jīng)常有香客問我,道長昨悼,這世上最難降的妖魔是什么蝗锥? 我笑而不...
    開封第一講書人閱讀 58,842評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮率触,結(jié)果婚禮上终议,老公的妹妹穿的比我還像新娘。我一直安慰自己葱蝗,他們只是感情好穴张,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著两曼,像睡著了一般皂甘。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悼凑,一...
    開封第一講書人閱讀 51,679評論 1 305
  • 那天偿枕,我揣著相機(jī)與錄音,去河邊找鬼户辫。 笑死渐夸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的渔欢。 我是一名探鬼主播墓塌,決...
    沈念sama閱讀 40,406評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼膘茎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起酷誓,我...
    開封第一講書人閱讀 39,311評論 0 276
  • 序言:老撾萬榮一對情侶失蹤披坏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后盐数,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體棒拂,經(jīng)...
    沈念sama閱讀 45,767評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了帚屉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谜诫。...
    茶點(diǎn)故事閱讀 40,090評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖攻旦,靈堂內(nèi)的尸體忽然破棺而出喻旷,到底是詐尸還是另有隱情,我是刑警寧澤牢屋,帶...
    沈念sama閱讀 35,785評論 5 346
  • 正文 年R本政府宣布且预,位于F島的核電站,受9級特大地震影響烙无,放射性物質(zhì)發(fā)生泄漏锋谐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評論 3 331
  • 文/蒙蒙 一截酷、第九天 我趴在偏房一處隱蔽的房頂上張望涮拗。 院中可真熱鬧,春花似錦迂苛、人聲如沸三热。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,988評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽康铭。三九已至,卻和暖如春赌髓,著一層夾襖步出監(jiān)牢的瞬間从藤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,101評論 1 271
  • 我被黑心中介騙來泰國打工锁蠕, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留夷野,地道東北人。 一個月前我還...
    沈念sama閱讀 48,298評論 3 372
  • 正文 我出身青樓荣倾,卻偏偏與公主長得像悯搔,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子舌仍,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評論 2 355

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