iOS WKWebView同步Cookies問題

之前在項目中使用WKWebView加載web網(wǎng)頁時,出現(xiàn)Cookies在App端不同步的問題,在UIWebView中卻是好用的,以為是WKWebView的坑,就通過JS交互的方式解決的,實際上這樣并不好,這樣做不但即時性不好,而且還浪費帶寬,現(xiàn)在找到原因了,在此記錄一下加深記憶。

這是Demo

更新-發(fā)現(xiàn)個問題:如果使用模擬器測試的話需要配合Charles軟件測試,不然不準。

WKWebView使用的內(nèi)核和UIWebView不同,在使用UIWebView時,在沙盒目錄下會生成一個Library/Cookies文件夾。


UIWebView的沙盒目錄

文件夾下就是保存的Cookies,在Library/preference中也有一個plist文件,從中也可以看到保存的Cookies


Preference中的Cookies.plist

而WKWebView則會在Library文件夾下生成一個WebKit文件夾,這里面都是只能看到文件夾,看不到Cookies,所以我們需要在平時使用WKWebView時做一些處理,通常有三種方式。
拼接Cookies的方式(常用)

原來的WKWebView加載url時是這樣的

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[self.wkWebView loadRequest:request];

現(xiàn)在做出修改如下:

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
request.allHTTPHeaderFields = dict;
[self.wkWebView loadRequest:request];

因為WKWebView的Cookies是WebKit的,和NSHTTPCookieStorage不是同步的,所以我們在加載網(wǎng)頁的時候要拼接上去。
同樣為了解決跨域問題,在代理中每次跳轉(zhuǎn)之前拼接Cookies

- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    NSURL *url = navigationAction.request.URL;
    [self wkWebViewWillStart:url];
    //為了解決跨域問題,每次跳轉(zhuǎn)url時把cookies拼接上
    NSMutableURLRequest *request = (NSMutableURLRequest *)navigationAction.request;
    NSArray *cookies = [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies];
    NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:cookies];
    request.allHTTPHeaderFields = dict;
    
    decisionHandler(WKNavigationActionPolicyAllow);
}
注入JS代碼的方式
//通過注入JS解決Cookies不同步的問題
- (WKUserScript *)injectCookieScript{
    WKUserScript * cookieScript = [[WKUserScript alloc] initWithSource:[self cookieString] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    return cookieScript;
}

- (NSString *)cookieString
{
    NSMutableString *script = [NSMutableString string];
    [script appendString:@"var cookieNames = document.cookie.split('; ').map(function(cookie) { return cookie.split('=')[0] } );\n"];
    for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
        
        if ([cookie.value rangeOfString:@"'"].location != NSNotFound) {
            continue;
        }
        
        NSString *string = [NSString stringWithFormat:@"%@=%@;domain=%@;path=%@",
                            cookie.name,
                            cookie.value,
                            cookie.domain,
                            cookie.path ?: @"/"];
        
        [script appendFormat:@"if (cookieNames.indexOf('%@') == -1) { document.cookie='%@'; };\n", cookie.name, string];
    }
    return script;
}

這種就是通過document.cookie同步到NSHTTPCookieStorage,簡單方便。

WKWebsiteDataStore

在WKWebView中設(shè)置下面這句就可以了,他可以同步NSHTTPCookieStorage和WKWebView的Cookies,但是目前只支持iOS11.0以上的系統(tǒng)。

[WKWebsiteDataStore defaultDataStore].httpCookieStore;

以上就是WKWebView解決Cookies與NSHTTPCookieStorage不同步的問題。
Demo

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容