級別: ★☆☆☆☆
標籤:「iOS 」「UIWebView注入Cookie」「WKWebView注入Cookie」
作者: WYW
審校: QiShare團隊
前言 上一篇文章中,筆者分享了Cookie簡介,在這篇文章中,筆者將在分享原生App中,嵌入UIWebView、WKWebView時,注入Cookie、及獲取服務端返回的響應頭中的Cookie。
為什麼要在UIWebView、WKWebView中注入Cookie
筆者設想了如下場景:
有時App中不僅僅會有原生的介面,還會有嵌入的UIWebView,或者是WKWebView。 比如說有一個App QiShare,嵌入了簡書的網頁。那麼,對於一個使用繁體的使用者,我們可以在載入簡書WebView的時候,在Cookie中設定local為zh-TW,這樣使用者可以從原生QiShare App,切換到瀏覽簡書WebView的時候,仍然看到的是繁體的內容。
另外,仍然以簡書為例,筆者在使用WebView訪問QiShare的網址的時候發現,是“已關注”狀態,這一點是通過在Cookie中設定remeber_user_token做到的。
具體點描述這個例子
以訪問簡書QiShare Cookie簡介為例:筆者使用UIWebView在載入Cookie簡介頁面的時候,在Cookie中設定了local為zh-TW。不過首次載入的時候,不會直接顯示為繁體,筆者以為原因是首次簡書WebView,簡書服務端還沒有返回相應繁體資訊。不過筆者第二次開啟簡書的其他WebView的時候,仍然沒有顯示為繁體,這一點還有點納悶。
筆者試了一下,當我們開啟QiShare的連結,可以發現顯示內容已經為繁體了。
因為上邊的繁體顯示不穩定,我們還通過啟動WebView前,注入Cookie,通過檢視開啟WebView後對QiShare關注狀態來說明Cookie中remember_user_token的作用,開啟WebView後,QiShare的關注狀態,顯示已關注。這需要我們在簡書的WebView上登入過帳號(在模擬器上如果想登入簡書的UIWebView,可以開啟任意一篇文章,然後點贊,便可以到WebView的登入介面),然後,在Cookie裡邊會有個remember_user_token來告訴我們是已關注的狀態。
UIWebView 注入Cookie:
筆者先以UIWebView載入QiShare簡書,設定Cookie中的locale為zh-TW,為例說明UIWebView注入Cookie,如下程式碼可以做到設定Cookie中代表本地的語言的引數locale為'繁體'(zh-TW)。
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效果如下圖,可以看到在“已關注”,“最新評論”,“熱門”等部分已經顯示為了繁體。
使用Charles檢視Cookie注入效果如下圖:
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注入效果如下圖:
Demo:
更多相關內容,可檢視 QiNetwork
參考學習網址
小編微信:可加並拉入《QiShare技術交流群》。
關注我們的途徑有:
QiShare(簡書)
QiShare(掘金)
QiShare(知乎)
QiShare(GitHub)
QiShare(CocoaChina)
QiShare(StackOverflow)
QiShare(微信公眾號)
推薦文章:
Cookie簡介
iOS 圖示&啟動圖生成器(一)
演算法小專欄:“D&C思想”與“快速排序”
iOS 避免常見崩潰(二)
演算法小專欄:選擇排序
iOS Runloop(一)
iOS 常用除錯方法:LLDB命令
iOS 常用除錯方法:斷點
奇舞週刊