將cookie同步到WebView(推薦)
參考:
文/CrazyCodeBoy(簡(jiǎn)書作者)
android WebView 和 HttpClient cookie同步
原理分析:
-
WebView是基于webkit內(nèi)核的UI控件虱黄,相當(dāng)于一個(gè)瀏覽器客戶端悦即。它會(huì)在本地維護(hù)每次會(huì)話的cookie(保存在data/data/package_name/app_WebView/Cookies.db)。如圖:
當(dāng)WebView加載URL的時(shí)候,WebView會(huì)從本地讀取該URL對(duì)應(yīng)的cookie橱乱,并攜帶該cookie與服務(wù)器進(jìn)行通信辜梳。WebView通過android.webkit.CookieManager類來維護(hù)cookie。CookieManager是WebView的cookie管理類泳叠。
- CookieManager.setCookie()方法:
/**
* Sets a cookie for the given URL. Any existing cookie with the same host,
* path and name will be replaced with the new cookie. The cookie being set
* must not have expired and must not be a session cookie, otherwise it
* will be ignored.
*
* @param url the URL for which the cookie is set
* @param value the cookie as a string, using the format of the 'Set-Cookie'
* HTTP response header
*/
public void setCookie(String url, String value) {
throw new MustOverrideException();
}
注:host作瞄、path和name相同的cookie 會(huì)被新的給替換掉,注意是host危纫、path和name都相同的宗挥。
url參數(shù)是你要為哪個(gè)cookie設(shè)置节预,而value和服務(wù)器返回設(shè)置sookie的方法'Set-Cookie‘是一致的。
也就是一個(gè)url的多個(gè)cookie属韧,要調(diào)用多次setCookie安拟,而每一次調(diào)用value的值都類似于:
cookie + ";Max-Age=3600" + ";Domain=.163.com" + ";Path = /" // 當(dāng)然還可以加上版本等信息
一般寫法:
//value參數(shù)不要忘記加domain和path
cookieManager.setCookie(cookie.getDomain(), cookie.getName() + "=" + cookie.getValue()
+ "; domain=" + cookie.getDomain() + "; path=" + cookie.getPath());
注意這里為什么第一個(gè)參數(shù)寫了個(gè)cookie.getDomain(),而不是像api里邊說的url這涉及到了cookie的知識(shí)宵喂,設(shè)置cookie時(shí)糠赦,會(huì)先檢測(cè)cookie的Domain是否和url網(wǎng)址的域名一致,如果不一致設(shè)置cookie失敗锅棕。所以u(píng)rl在里邊起到作用拙泽,就是檢測(cè)Domain域名。
注意裸燎,只有cookie的domain和path與請(qǐng)求的URL匹配才會(huì)發(fā)送這個(gè)cookie顾瞻,所以設(shè)置cookie的時(shí)候value參數(shù)不要忘記加domain和path,如上面代碼德绿。
如何做:
下面我們就通過CookieManager將cookie同步到WebView中荷荤。之前同步cookie需要用到CookieSyncManager類,現(xiàn)在這個(gè)類已經(jīng)被deprecated移稳。如今WebView已經(jīng)可以在需要的時(shí)候自動(dòng)同步cookie了蕴纳,所以不再需要?jiǎng)?chuàng)建CookieSyncManager類的對(duì)象來進(jìn)行強(qiáng)制性的同步cookie了。現(xiàn)在只需要獲得 CookieManager的對(duì)象將cookie設(shè)置進(jìn)去就可以了个粱。
- 第一步:登錄時(shí)從服務(wù)器的返回頭中取出cookie**根據(jù)Http請(qǐng)求的客戶端不同古毛,取cookie的方式也不同,我就不一一羅列了都许,需要的網(wǎng)友可以自行Google稻薇,以HttpURLcollection為例:
String cookieStr = conn.getHeaderField("Set-Cookie");
- 第二步:將cookie同步到WebView中**
/**
* 將cookie同步到WebView
* @param url WebView要加載的url
* @param cookie 要同步的cookie
* @return true 同步cookie成功,false同步cookie失敗
* @Author JPH
*/
public static boolean syncCookie(String url,String cookie) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(context);
}
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setCookie(url, cookie);//如果沒有特殊需求胶征,這里只需要將session id以"key=value"形式作為cookie即可
String newCookie = cookieManager.getCookie(url);
return TextUtils.isEmpty(newCookie)?false:true;
}
如圖(url可以只到path即可):
如果設(shè)置成功塞椎,通過cookieManager.getCookie(url)
方法就可取得剛才設(shè)置的cookie,下面我們查看一下Cookie數(shù)據(jù)庫(kù)中發(fā)生的變化弧烤。如圖:
提示:
同步cookie要在WebView加載url之前忱屑,否則WebView無(wú)法獲得相應(yīng)的cookie蹬敲,也就無(wú)法通過驗(yàn)證暇昂。
每次登錄成功后都需要調(diào)用"syncCookie"方法將cookie同步到WebView中,同時(shí)也達(dá)到了更新WebView的cookie伴嗡。如果登錄后沒有及時(shí)將cookie同步到WebView可能導(dǎo)致WebView拿的是舊的session id和服務(wù)器進(jìn)行通信急波。
優(yōu)點(diǎn):
方便,只需要在登陸后將cookie同步到WebView即可瘪校,省去了每次請(qǐng)求都需要設(shè)置一次的繁瑣澄暮。
兼容性好名段,因?yàn)槭窍到y(tǒng)原生支持的,所以兼容性自然比方式一要好泣懊,不存在cookie被攔截的問題伸辟。
PS
Cookie相關(guān)的Http頭
有 兩個(gè)Http頭部和Cookie有關(guān):Set-Cookie和Cookie。
- Set-Cookie由服務(wù)器發(fā)送馍刮,它包含在響應(yīng)請(qǐng)求的頭部中信夫。它用于在客戶端創(chuàng)建一個(gè)Cookie
- Cookie頭由客戶端發(fā)送,包含在HTTP請(qǐng)求的頭部中卡啰。注意静稻,只有cookie的domain和path與請(qǐng)求的URL匹配才會(huì)發(fā)送這個(gè)cookie。
Set-Cookie響應(yīng)頭的格式如下所示:
Set-Cookie: <name>=<value>[; <name>=<value>]...
[; expires=<date>][; domain=<domain_name>]
[; path=<some_path>][; secure][; httponly]
expires=<date>: 設(shè)置cookie的有效期匈辱,如果cookie超過date所表示的日期時(shí)振湾,cookie將失效。
如果沒有設(shè)置這個(gè)選項(xiàng)亡脸,那么cookie將在瀏覽器關(guān)閉時(shí)失效押搪。
secure : 表示cookie只能被發(fā)送到http服務(wù)器。
httponly : 表示cookie不能被客戶端腳本獲取到浅碾。
注:臨時(shí)cookie(沒有expires參數(shù)的cookie)不能帶有domain選項(xiàng)嵌言。
當(dāng)客戶端發(fā)送一個(gè)http請(qǐng)求時(shí),會(huì)將有效的cookie一起發(fā)送給服務(wù)器及穗。
如果一個(gè)cookie的domain和path參數(shù)和URL匹配摧茴,那么這個(gè)cookie就是有效的。