iOS UIWebView、WKWebView注入Cookie

級別: ★☆☆☆☆
標籤:「iOS 」「UIWebView注入Cookie」「WKWebView注入Cookie」
做者: WYW
審校: QiShare團隊php


前言 上一篇文章中,筆者分享了Cookie簡介,在這篇文章中,筆者將在分享原生App中,嵌入UIWebView、WKWebView時,注入Cookie、及獲取服務端返回的響應頭中的Cookie。git

爲何要在UIWebView、WKWebView中注入Cookie

筆者設想了以下場景:github

有時App中不單單會有原生的界面,還會有嵌入的UIWebView,或者是WKWebView。 好比說有一個App QiShare,嵌入了簡書的網頁。那麼,對於一個使用繁體的用戶,咱們能夠在加載簡書WebView的時候,在Cookie中設置local爲zh-TW,這樣用戶能夠從原生QiShare App,切換到瀏覽簡書WebView的時候,仍然看到的是繁體的內容。web

另外,仍然以簡書爲例,筆者在使用WebView訪問QiShare的網址的時候發現,是「已關注」狀態,這一點是經過在Cookie中設置remeber_user_token作到的。算法

具體點描述這個例子bash

以訪問簡書QiShare Cookie簡介爲例:筆者使用UIWebView在加載Cookie簡介頁面的時候,在Cookie中設置了local爲zh-TW。不過首次加載的時候,不會直接顯示爲繁體,筆者覺得緣由是首次簡書WebView,簡書服務端尚未返回相應繁體信息。不過筆者第二次打開簡書的其餘WebView的時候,仍然沒有顯示爲繁體,這一點還有點納悶。微信

筆者試了一下,當咱們打開QiShare的連接,能夠發現顯示內容已經爲繁體了。cookie

由於上邊的繁體顯示不穩定,咱們還經過啓動WebView前,注入Cookie,經過查看打開WebView後對QiShare關注狀態來講明Cookie中remember_user_token的做用,打開WebView後,QiShare的關注狀態,顯示已關注。這須要咱們在簡書的WebView上登陸過賬號(在模擬器上若是想登陸簡書的UIWebView,能夠打開任意一篇文章,而後點贊,即可以到WebView的登陸界面),而後,在Cookie裏邊會有個remember_user_token來告訴咱們是已關注的狀態。dom

UIWebView 注入Cookie:

筆者先以UIWebView加載QiShare簡書,設置Cookie中的locale爲zh-TW,爲例說明UIWebView注入Cookie,以下代碼能夠作到設置Cookie中表明本地的語言的參數locale爲'繁體'(zh-TW)。oop

NSDictionary *keyPropertiesLocal = @{
                                    NSHTTPCookieName: @"locale",
                                    NSHTTPCookieValue: @"zh-TW",
                                    NSHTTPCookiePath: @"/",
                                    NSHTTPCookieDomain: @".jianshu.com"
                                    };
                                    
	NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:keyPropertiesLocal];
	
	[[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
	
	NSURL *url = [NSURL URLWithString:@"https://www.jianshu.com/p/1174d1dbe650"];
	NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
	[_webView loadRequest:request];
	
複製代碼

使用[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:設置Cookie的方式能夠作到,每次加載UIWebView的時候,都會自動攜帶已注入的Cookie,有點全局性的效果。

筆者寫了個使用NSHTTPCookieStorage 注入Cookie的方法:

代碼以下:

//! 生成指定cookieName cookieValue cookiePath cookieDomain 的NSHTTPCookie 實例
- (NSHTTPCookie *)cookieWithName:(NSString *)name cookieValue:(NSString *)value  cookiePath:(NSString *)path cookieDomain:(NSString *)domain {
    
    NSDictionary *keyProperties = @{
                                         NSHTTPCookieName: name,
                                         NSHTTPCookieValue: value,
                                         NSHTTPCookiePath: path,
                                         NSHTTPCookieDomain: domain
                                         };
    
    NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:keyProperties];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    return cookie;
}
複製代碼
//! 設置 (生成指定cookieName cookieValue cookiePath cookieDomain 的NSHTTPCookie 實例) 到NSHTTPCookieStorage
- (NSHTTPCookie *)setCookieWithName:(NSString *)name cookieValue:(NSString *)value  cookiePath:(NSString *)path cookieDomain:(NSString *)domain {
    
    if (!name || !value || !path || !domain) {
        return nil;
    }
    NSHTTPCookie *cookie = [self cookieWithName:name cookieValue:value cookiePath:path cookieDomain:domain];
    [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookie:cookie];
    
    return cookie;
}

複製代碼

使用方式如:

NSURL * url = [NSURL URLWithString:@"https://www.jianshu.com/p/1174d1dbe650"];
    [self setCookieWithName:@"local" cookieValue:@"zh-TW" cookiePath:@"/" cookieDomain:kJianshuDomain];
    [self setCookieWithName:@"QiShareToken" cookieValue:@"QiShareTokenValue" cookiePath:@"/" cookieDomain:kJianshuDomain];
    [self setCookieWithName:@"QiShareKey" cookieValue:@"QiShareValue" cookiePath:@"/" cookieDomain:kJianshuDomain];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    [_webView loadRequest:request];
複製代碼

在Cookie中設置過local後的Demo效果以下圖,能夠看到在「已關注」,「最新評論」,「熱門」等部分已經顯示爲了繁體。

UIWebView_zh-TW.gif

使用Charles查看Cookie注入效果以下圖:

UIWebViewCookie.png

WKWebView注入Cookie:

筆者以WKWebView加載掘金url,且加載過程當中WKWebView注入Cookie,WKWebView設置以下Cookie(設置一個名爲QiShareAuth1 值也爲QiShareAuth1的Cookie;另外設置一個名爲QiShareAuth2 值也爲QiShareAuth2的Cookie)。 能夠使用以下代碼:

在建立WKWebView的時候就已經注入了要設置的Cookie

WKUserContentController *userContentController = [WKUserContentController new];
    NSString *cookieSource = [NSString stringWithFormat:@"document.cookie = 'QiShareAuth1=QiShareAuth1';document.cookie = 'QiShareAuth2=QiShareAuth2';"];
    WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:cookieSource injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [userContentController addUserScript:cookieScript];
    WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
    config.userContentController = userContentController;
    
    NSURL *juejinUrl = [NSURL URLWithString:@"https://juejin.im"];
    NSMutableURLRequest *mJuejinRequest = [[NSMutableURLRequest alloc] initWithURL:juejinUrl];
    // [mJuejinRequest addValue:@"QiShareAuth1=QiShareAuth1;QiShareAuth2=QiShareAuth2" forHTTPHeaderField:@"Cookie"];
    WKWebView *wkWebV  = [[WKWebView alloc] initWithFrame:self.view.bounds configuration:config];
    _wkWebView = wkWebV;
   [self.view addSubview:wkWebV];

複製代碼

仍有問題?

筆者用Demo QiNetwork查看使用如上代碼效果的時候,覺得已經搞定了問題,結果發現,WKWebView在首次加載請求的時候,並無攜帶咱們注入的Cookie。查看了相關資料後有博客說起能夠在加載請求前,使用給_wkWebView.configuration.websiteDataStore.httpCookieStore設置Cookie的方式,解決問題,不過筆者試過了,並無達到預期效果。

筆者最終採用的是在首次加載請求的時候,在使用上述代碼的狀況下,一樣給mJuejinRequest添加了一次請求所需的cookie,相關代碼以下:

[mJuejinRequest addValue:@"QiShareAuth1=QiShareAuth1;QiShareAuth2=QiShareAuth2" forHTTPHeaderField:@"Cookie"];
複製代碼

上述代碼也是可用於想設置某個單個的請求的Cookie。 使用Charles查看Cookie注入效果以下圖:

WKWebViewCookie1.png

WKWebViewCookie2.png

Demo:

更多相關內容,可查看 QiNetwork

參考學習網址


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

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

推薦文章:
Cookie簡介
iOS 圖標&啓動圖生成器(一)
算法小專欄:「D&C思想」與「快速排序」
iOS 避免常見崩潰(二)
算法小專欄:選擇排序
iOS Runloop(一)
iOS 經常使用調試方法:LLDB命令
iOS 經常使用調試方法:斷點
奇舞週刊

相關文章
相關標籤/搜索